ReactOS 0.4.17-dev-1321-g5c122a9
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 NTAPI 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 NTAPI 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 2503 of file storahci.c.

2507{
2510
2511 if (Queue->Tail == ((Queue->Head + 1) % MAXIMUM_QUEUE_BUFFER_SIZE))
2512 return FALSE;
2513
2514 Queue->Buffer[Queue->Head++] = Srb;
2516
2517 return TRUE;
2518}// -- 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:2231
#define NT_ASSERT
Definition: rtlfuncs.h:3334

Referenced by AhciCompleteIssuedSrb(), and AhciProcessIO().

◆ AhciActivatePort()

VOID AhciActivatePort ( __in PAHCI_PORT_EXTENSION  PortExtension)

Definition at line 1492 of file storahci.c.

1495{
1497 ULONG QueueSlots, slotToActivate, tmp;
1498 PAHCI_ADAPTER_EXTENSION AdapterExtension;
1499
1500 AhciDebugPrint("AhciActivatePort()\n");
1501
1502 AdapterExtension = PortExtension->AdapterExtension;
1503 QueueSlots = PortExtension->QueueSlots;
1504
1505 if (QueueSlots == 0)
1506 {
1507 return;
1508 }
1509
1510 // section 3.3.14
1511 // Bits in this field shall only be set to ‘1’ by software when PxCMD.ST is set to ‘1’
1512 cmd.Status = StorPortReadRegisterUlong(AdapterExtension, &PortExtension->Port->CMD);
1513
1514 if (cmd.ST == 0) // PxCMD.ST == 0
1515 {
1516 return;
1517 }
1518
1519 // get the lowest set bit
1520 tmp = QueueSlots & (QueueSlots - 1);
1521
1522 if (tmp == 0)
1523 slotToActivate = QueueSlots;
1524 else
1525 slotToActivate = (QueueSlots & (~tmp));
1526
1527 // mark that bit off in QueueSlots
1528 // so we can know we it is really needed to activate port or not
1529 PortExtension->QueueSlots &= ~slotToActivate;
1530 // mark this CommandIssuedSlots
1531 // to validate in completeIssuedCommand
1532 PortExtension->CommandIssuedSlots |= slotToActivate;
1533
1534 // tell the HBA to issue this Command Slot to the given port
1535 StorPortWriteRegisterUlong(AdapterExtension, &PortExtension->Port->CI, slotToActivate);
1536
1537 return;
1538}// -- 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 2395 of file storahci.c.

2398{
2399 ULONG ticks;
2400 AHCI_GHC ghc;
2402
2403 AhciDebugPrint("AhciAdapterReset()\n");
2404
2405 abar = AdapterExtension->ABAR_Address;
2406 if (abar == NULL) // basic sanity
2407 {
2408 return FALSE;
2409 }
2410
2411 // HR -- Very first bit (lowest significant)
2412 ghc.HR = 1;
2413 StorPortWriteRegisterUlong(AdapterExtension, &abar->GHC, ghc.Status);
2414
2415 for (ticks = 0; ticks < 50; ++ticks)
2416 {
2417 ghc.Status = StorPortReadRegisterUlong(AdapterExtension, &abar->GHC);
2418 if (ghc.HR == 0)
2419 {
2420 break;
2421 }
2423 }
2424
2425 if (ticks == 50)// 1 second
2426 {
2427 AhciDebugPrint("\tDevice Timeout\n");
2428 return FALSE;
2429 }
2430
2431 return TRUE;
2432}// -- AhciAdapterReset();
#define NULL
Definition: types.h:112
STORPORT_API VOID NTAPI StorPortStallExecution(_In_ ULONG Delay)
Definition: storport.c:1969
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 _AHCI_COMMAND_HEADER * PAHCI_COMMAND_HEADER
struct _AHCI_RECEIVED_FIS * PAHCI_RECEIVED_FIS
struct _AHCI_COMMAND_HEADER AHCI_COMMAND_HEADER
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:2445
#define MAXIMUM_AHCI_PORT_COUNT
Definition: storahci.h:21
#define AHCI_Global_Port_CAP_NCS(x)
Definition: storahci.h:81
STORPORT_API PVOID NTAPI StorPortGetUncachedExtension(_In_ PVOID HwDeviceExtension, _In_ PPORT_CONFIGURATION_INFORMATION ConfigInfo, _In_ ULONG NumberOfBytes)
Definition: storport.c:1307
struct _AHCI_PORT_EXTENSION::@1584 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 1221 of file storahci.c.

1225{
1226 PAHCI_COMMAND_TABLE cmdTable;
1227
1228 UNREFERENCED_PARAMETER(PortExtension);
1229
1230 AhciDebugPrint("AhciATA_CFIS()\n");
1231
1232 cmdTable = (PAHCI_COMMAND_TABLE)SrbExtension;
1233
1234 AhciZeroMemory((PCHAR)cmdTable->CFIS, sizeof(cmdTable->CFIS));
1235
1236 cmdTable->CFIS[AHCI_ATA_CFIS_FisType] = FIS_TYPE_REG_H2D; // FIS Type
1237 cmdTable->CFIS[AHCI_ATA_CFIS_PMPort_C] = (1 << 7); // PM Port & C
1238 cmdTable->CFIS[AHCI_ATA_CFIS_CommandReg] = SrbExtension->CommandReg;
1239
1240 cmdTable->CFIS[AHCI_ATA_CFIS_FeaturesLow] = SrbExtension->FeaturesLow;
1241 cmdTable->CFIS[AHCI_ATA_CFIS_LBA0] = SrbExtension->LBA0;
1242 cmdTable->CFIS[AHCI_ATA_CFIS_LBA1] = SrbExtension->LBA1;
1243 cmdTable->CFIS[AHCI_ATA_CFIS_LBA2] = SrbExtension->LBA2;
1244 cmdTable->CFIS[AHCI_ATA_CFIS_Device] = SrbExtension->Device;
1245 cmdTable->CFIS[AHCI_ATA_CFIS_LBA3] = SrbExtension->LBA3;
1246 cmdTable->CFIS[AHCI_ATA_CFIS_LBA4] = SrbExtension->LBA4;
1247 cmdTable->CFIS[AHCI_ATA_CFIS_LBA5] = SrbExtension->LBA5;
1248 cmdTable->CFIS[AHCI_ATA_CFIS_FeaturesHigh] = SrbExtension->FeaturesHigh;
1249 cmdTable->CFIS[AHCI_ATA_CFIS_SectorCountLow] = SrbExtension->SectorCountLow;
1250 cmdTable->CFIS[AHCI_ATA_CFIS_SectorCountHigh] = SrbExtension->SectorCountHigh;
1251
1252 return 5;
1253}// -- AhciATA_CFIS();
struct _AHCI_COMMAND_TABLE * PAHCI_COMMAND_TABLE
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
#define AHCI_ATA_CFIS_Device
Definition: storahci.h:53
#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 1268 of file storahci.c.

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

1850{
1851 ULONG SrbFlags, DataBufferLength;
1852 PAHCI_SRB_EXTENSION SrbExtension;
1853 PAHCI_PORT_EXTENSION PortExtension;
1854
1855 AhciDebugPrint("AhciATAPICommand()\n");
1856
1857 SrbFlags = Srb->SrbFlags;
1858 SrbExtension = GetSrbExtension(Srb);
1860 PortExtension = &AdapterExtension->PortExtension[Srb->PathId];
1861
1862 NT_ASSERT(PortExtension->DeviceParams.DeviceType == AHCI_DEVICE_TYPE_ATAPI);
1863
1864 NT_ASSERT(SrbExtension != NULL);
1865
1867 SrbExtension->Flags = 0;
1868
1869 if (SrbFlags & SRB_FLAGS_DATA_IN)
1870 {
1871 SrbExtension->Flags |= ATA_FLAGS_DATA_IN;
1872 }
1873
1874 if (SrbFlags & SRB_FLAGS_DATA_OUT)
1875 {
1876 SrbExtension->Flags |= ATA_FLAGS_DATA_OUT;
1877 }
1878
1879 SrbExtension->FeaturesLow = 0;
1880
1881 SrbExtension->CompletionRoutine = NULL;
1882
1883 NT_ASSERT(Cdb != NULL);
1884 switch(Cdb->CDB10.OperationCode)
1885 {
1886 case SCSIOP_INQUIRY:
1887 SrbExtension->Flags |= ATA_FLAGS_DATA_IN;
1889 break;
1890 case SCSIOP_READ:
1891 SrbExtension->Flags |= ATA_FLAGS_USE_DMA;
1892 SrbExtension->FeaturesLow = 0x5;
1893 break;
1894 case SCSIOP_WRITE:
1895 SrbExtension->Flags |= ATA_FLAGS_USE_DMA;
1896 SrbExtension->FeaturesLow = 0x1;
1897 break;
1898 }
1899
1900 SrbExtension->CommandReg = IDE_COMMAND_ATAPI_PACKET;
1901
1902 SrbExtension->LBA0 = 0;
1903 SrbExtension->LBA1 = (UCHAR)(DataBufferLength >> 0);
1904 SrbExtension->LBA2 = (UCHAR)(DataBufferLength >> 8);
1905 SrbExtension->Device = 0;
1906 SrbExtension->LBA3 = 0;
1907 SrbExtension->LBA4 = 0;
1908 SrbExtension->LBA5 = 0;
1909 SrbExtension->FeaturesHigh = 0;
1910 SrbExtension->SectorCountLow = 0;
1911 SrbExtension->SectorCountHigh = 0;
1912
1913 if ((SrbExtension->Flags & ATA_FLAGS_DATA_IN) || (SrbExtension->Flags & ATA_FLAGS_DATA_OUT))
1914 {
1915 SrbExtension->pSgl = (PLOCAL_SCATTER_GATHER_LIST)StorPortGetScatterGatherList(AdapterExtension, Srb);
1916 }
1917
1918 return SRB_STATUS_PENDING;
1919}// -- 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:2566
VOID AtapiInquiryCompletion(__in PVOID _Extension, __in PVOID _Srb)
Definition: storahci.c:1640
#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 HwDeviceExtension, _In_ PSCSI_REQUEST_BLOCK Srb)
Definition: storport.c:1269
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
unsigned char UCHAR
Definition: typedefs.h:53
#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

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 1316 of file storahci.c.

1320{
1321 ULONG index;
1322 PAHCI_COMMAND_TABLE cmdTable;
1324 PAHCI_ADAPTER_EXTENSION AdapterExtension;
1325
1326 AhciDebugPrint("AhciBuild_PRDT()\n");
1327
1328 sgl = SrbExtension->pSgl;
1329 cmdTable = (PAHCI_COMMAND_TABLE)SrbExtension;
1330 AdapterExtension = PortExtension->AdapterExtension;
1331
1332 NT_ASSERT(sgl != NULL);
1334
1335 for (index = 0; index < sgl->NumberOfElements; index++)
1336 {
1338
1339 cmdTable->PRDT[index].DBA = sgl->List[index].PhysicalAddress.LowPart;
1340 if (IsAdapterCAPS64(AdapterExtension->CAP))
1341 {
1342 cmdTable->PRDT[index].DBAU = sgl->List[index].PhysicalAddress.HighPart;
1343 }
1344
1345 // Data Byte Count (DBC): A ‘0’ based value that Indicates the length, in bytes, of the data block.
1346 // A maximum of length of 4MB may exist for any entry. Bit ‘0’ of this field must always be ‘1’ to
1347 // indicate an even byte count. A value of ‘1’ indicates 2 bytes, ‘3’ indicates 4 bytes, etc.
1348 cmdTable->PRDT[index].DBC = sgl->List[index].Length - 1;
1349 }
1350
1351 return sgl->NumberOfElements;
1352}// -- 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:5673
ULONG LowPart
Definition: typedefs.h:106

Referenced by AhciProcessSrb().

◆ AhciCommandCompletionDpcRoutine()

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

Definition at line 422 of file storahci.c.

428{
430 PAHCI_SRB_EXTENSION SrbExtension;
431 STOR_LOCK_HANDLE lockhandle = {0};
433 PAHCI_ADAPTER_EXTENSION AdapterExtension;
434 PAHCI_PORT_EXTENSION PortExtension;
435
438
439 AhciDebugPrint("AhciCommandCompletionDpcRoutine()\n");
440
441 AdapterExtension = (PAHCI_ADAPTER_EXTENSION)HwDeviceExtension;
442 PortExtension = (PAHCI_PORT_EXTENSION)SystemArgument1;
443
444 StorPortAcquireSpinLock(AdapterExtension, InterruptLock, NULL, &lockhandle);
445 Srb = RemoveQueue(&PortExtension->CompletionQueue);
446 StorPortReleaseSpinLock(AdapterExtension, &lockhandle);
447
448 NT_ASSERT(Srb != NULL);
449
451 {
453 }
454 else
455 {
456 return;
457 }
458
459 SrbExtension = GetSrbExtension(Srb);
460
461 CompletionRoutine = SrbExtension->CompletionRoutine;
463
464 // now it's completion routine responsibility to set SrbStatus
465 CompletionRoutine(PortExtension, Srb);
466
467 StorPortNotification(RequestComplete, AdapterExtension, Srb);
468
469 return;
470}// -- AhciCommandCompletionDpcRoutine();
@ RequestComplete
Definition: srb.h:531
#define SRB_STATUS_SUCCESS
Definition: srb.h:341
_In_ PIRP _In_ PIO_COMPLETION_ROUTINE CompletionRoutine
Definition: kse.h:80
FORCEINLINE PVOID RemoveQueue(__inout PAHCI_QUEUE Queue)
Definition: storahci.c:2534
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:1550
FORCEINLINE VOID StorPortReleaseSpinLock(_In_ PVOID DeviceExtension, _Inout_ PSTOR_LOCK_HANDLE LockHandle)
Definition: storport.h:7951
FORCEINLINE VOID StorPortAcquireSpinLock(_In_ PVOID DeviceExtension, _In_ STOR_SPINLOCK SpinLock, _In_ PVOID LockContext, _Inout_ PSTOR_LOCK_HANDLE LockHandle)
Definition: storport.h:7936
@ InterruptLock
Definition: storport.h:1434
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_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:756
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:757

Referenced by AhciHwPassiveInitialize().

◆ AhciCompleteIssuedSrb()

VOID AhciCompleteIssuedSrb ( __in PAHCI_PORT_EXTENSION  PortExtension,
__in ULONG  CommandsToComplete 
)

Definition at line 563 of file storahci.c.

567{
568 ULONG NCS, i;
570 PAHCI_SRB_EXTENSION SrbExtension;
571 PAHCI_ADAPTER_EXTENSION AdapterExtension;
572
573 AhciDebugPrint("AhciCompleteIssuedSrb()\n");
574
575 NT_ASSERT(CommandsToComplete != 0);
576
577 AhciDebugPrint("\tCompleted Commands: %d\n", CommandsToComplete);
578
579 AdapterExtension = PortExtension->AdapterExtension;
580 NCS = AHCI_Global_Port_CAP_NCS(AdapterExtension->CAP);
581
582 for (i = 0; i < NCS; i++)
583 {
584 if (((1 << i) & CommandsToComplete) != 0)
585 {
586 Srb = PortExtension->Slot[i];
587
588 if (Srb == NULL)
589 {
590 continue;
591 }
592
593 SrbExtension = GetSrbExtension(Srb);
594 NT_ASSERT(SrbExtension != NULL);
595
596 if (SrbExtension->CompletionRoutine != NULL)
597 {
598 AddQueue(&PortExtension->CompletionQueue, Srb);
599 StorPortIssueDpc(AdapterExtension, &PortExtension->CommandCompletion, PortExtension, Srb);
600 }
601 else
602 {
605 StorPortNotification(RequestComplete, AdapterExtension, Srb);
606 }
607 }
608 }
609
610 return;
611}// -- 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:2503
FORCEINLINE BOOLEAN StorPortIssueDpc(_In_ PVOID DeviceExtension, _In_ PSTOR_DPC Dpc, _In_ PVOID SystemArgument1, _In_ PVOID SystemArgument2)
Definition: storport.h:7917

Referenced by AhciInterruptHandler().

◆ AhciGetLba()

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

Definition at line 2597 of file storahci.c.

2601{
2602 ULONG64 lba = 0;
2603
2604 NT_ASSERT(Cdb != NULL);
2605 NT_ASSERT(CdbLength != 0);
2606
2607 if (CdbLength == 0x10)
2608 {
2609 REVERSE_BYTES_QUAD(&lba, Cdb->CDB16.LogicalBlock);
2610 }
2611 else
2612 {
2613 lba |= Cdb->CDB10.LogicalBlockByte3 << 0;
2614 lba |= Cdb->CDB10.LogicalBlockByte2 << 8;
2615 lba |= Cdb->CDB10.LogicalBlockByte1 << 16;
2616 lba |= Cdb->CDB10.LogicalBlockByte0 << 24;
2617 }
2618
2619 return lba;
2620}// -- AhciGetLba();
unsigned __int64 ULONG64
Definition: imports.h:198
#define REVERSE_BYTES_QUAD(Destination, Source)
Definition: scsi.h:3498
#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 992 of file storahci.c.

1000{
1001 AHCI_GHC ghc;
1002 ULONG index, pci_cfg_len;
1003 PACCESS_RANGE accessRange;
1004 UCHAR pci_cfg_buf[sizeof(PCI_COMMON_CONFIG)];
1005
1007 PPCI_COMMON_CONFIG pciConfigData;
1008 PAHCI_ADAPTER_EXTENSION adapterExtension;
1009
1010 AhciDebugPrint("AhciHwFindAdapter()\n");
1011
1014 UNREFERENCED_PARAMETER(ArgumentString);
1016
1017 adapterExtension = DeviceExtension;
1018 adapterExtension->SlotNumber = ConfigInfo->SlotNumber;
1019 adapterExtension->SystemIoBusNumber = ConfigInfo->SystemIoBusNumber;
1020
1021 // get PCI configuration header
1022 pci_cfg_len = StorPortGetBusData(
1023 adapterExtension,
1025 adapterExtension->SystemIoBusNumber,
1026 adapterExtension->SlotNumber,
1027 pci_cfg_buf,
1028 sizeof(PCI_COMMON_CONFIG));
1029
1030 if (pci_cfg_len != sizeof(PCI_COMMON_CONFIG))
1031 {
1032 AhciDebugPrint("\tpci_cfg_len != %d :: %d", sizeof(PCI_COMMON_CONFIG), pci_cfg_len);
1033 return SP_RETURN_ERROR;//Not a valid device at the given bus number
1034 }
1035
1036 pciConfigData = (PPCI_COMMON_CONFIG)pci_cfg_buf;
1037 adapterExtension->VendorID = pciConfigData->VendorID;
1038 adapterExtension->DeviceID = pciConfigData->DeviceID;
1039 adapterExtension->RevisionID = pciConfigData->RevisionID;
1040 // 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).
1041 adapterExtension->AhciBaseAddress = pciConfigData->u.type0.BaseAddresses[5] & (0xFFFFFFF0);
1042
1043 AhciDebugPrint("\tVendorID: %04x DeviceID: %04x RevisionID: %02x\n",
1044 adapterExtension->VendorID,
1045 adapterExtension->DeviceID,
1046 adapterExtension->RevisionID);
1047
1048 // 2.1.11
1049 abar = NULL;
1050 if (ConfigInfo->NumberOfAccessRanges > 0)
1051 {
1052 accessRange = *(ConfigInfo->AccessRanges);
1053 for (index = 0; index < ConfigInfo->NumberOfAccessRanges; index++)
1054 {
1055 if (accessRange[index].RangeStart.QuadPart == adapterExtension->AhciBaseAddress)
1056 {
1057 abar = StorPortGetDeviceBase(adapterExtension,
1058 ConfigInfo->AdapterInterfaceType,
1059 ConfigInfo->SystemIoBusNumber,
1060 accessRange[index].RangeStart,
1061 accessRange[index].RangeLength,
1062 !accessRange[index].RangeInMemory);
1063 break;
1064 }
1065 }
1066 }
1067
1068 if (abar == NULL)
1069 {
1070 AhciDebugPrint("\tabar == NULL\n");
1071 return SP_RETURN_ERROR; // corrupted information supplied
1072 }
1073
1074 adapterExtension->ABAR_Address = abar;
1075 adapterExtension->CAP = StorPortReadRegisterUlong(adapterExtension, &abar->CAP);
1076 adapterExtension->CAP2 = StorPortReadRegisterUlong(adapterExtension, &abar->CAP2);
1077 adapterExtension->Version = StorPortReadRegisterUlong(adapterExtension, &abar->VS);
1078 adapterExtension->LastInterruptPort = (ULONG)-1;
1079
1080 // 10.1.2
1081 // 1. Indicate that system software is AHCI aware by setting GHC.AE to ‘1’.
1082 // 3.1.2 -- AE bit is read-write only if CAP.SAM is '0'
1083 ghc.Status = StorPortReadRegisterUlong(adapterExtension, &abar->GHC);
1084 // AE := Highest Significant bit of GHC
1085 if (ghc.AE != 0)// Hmm, controller was already in power state
1086 {
1087 // reset controller to have it in known state
1088 AhciDebugPrint("\tAE Already set, Reset()\n");
1089 if (!AhciAdapterReset(adapterExtension))
1090 {
1091 AhciDebugPrint("\tReset Failed!\n");
1092 return SP_RETURN_ERROR;// reset failed
1093 }
1094 }
1095
1096 ghc.Status = 0;
1097 ghc.AE = 1;// only AE=1
1098 // tell the controller that we know about AHCI
1099 StorPortWriteRegisterUlong(adapterExtension, &abar->GHC, ghc.Status);
1100
1101 adapterExtension->IS = &abar->IS;
1102 adapterExtension->PortImplemented = StorPortReadRegisterUlong(adapterExtension, &abar->PI);
1103
1104 if (adapterExtension->PortImplemented == 0)
1105 {
1106 AhciDebugPrint("\tadapterExtension->PortImplemented == 0\n");
1107 return SP_RETURN_ERROR;
1108 }
1109
1110 ConfigInfo->Master = TRUE;
1111 ConfigInfo->AlignmentMask = 0x3;
1112 ConfigInfo->ScatterGather = TRUE;
1113 ConfigInfo->DmaWidth = Width32Bits;
1114 ConfigInfo->WmiDataProvider = FALSE;
1115 ConfigInfo->Dma32BitAddresses = TRUE;
1116
1117 if (IsAdapterCAPS64(adapterExtension->CAP))
1118 {
1119 ConfigInfo->Dma64BitAddresses = TRUE;
1120 }
1121
1122 ConfigInfo->MaximumNumberOfTargets = 1;
1123 ConfigInfo->ResetTargetSupported = TRUE;
1124 ConfigInfo->NumberOfPhysicalBreaks = 0x21;
1125 ConfigInfo->MaximumNumberOfLogicalUnits = 1;
1126 ConfigInfo->NumberOfBuses = MAXIMUM_AHCI_PORT_COUNT;
1127 ConfigInfo->MaximumTransferLength = MAXIMUM_TRANSFER_LENGTH;
1128 ConfigInfo->SynchronizationModel = StorSynchronizeFullDuplex;
1129
1130 // Turn IE -- Interrupt Enabled
1131 ghc.Status = StorPortReadRegisterUlong(adapterExtension, &abar->GHC);
1132 ghc.IE = 1;
1133 StorPortWriteRegisterUlong(adapterExtension, &abar->GHC, ghc.Status);
1134
1135 // allocate necessary resource for each port
1136 if (!AhciAllocateResourceForAdapter(adapterExtension, ConfigInfo))
1137 {
1139 return SP_RETURN_ERROR;
1140 }
1141
1142 for (index = 0; index < adapterExtension->PortCount; index++)
1143 {
1144 if ((adapterExtension->PortImplemented & (0x1 << index)) != 0)
1145 AhciPortInitialize(&adapterExtension->PortExtension[index]);
1146 }
1147
1148 return SP_RETURN_FOUND;
1149}// -- 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:2395
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:1060
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:1101
@ StorSynchronizeFullDuplex
Definition: storport.h:1418
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:3921
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 523 of file storahci.c.

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

Referenced by DriverEntry().

◆ AhciHwInterrupt()

BOOLEAN NTAPI AhciHwInterrupt ( __in PVOID  DeviceExtension)

Definition at line 721 of file storahci.c.

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

Referenced by DriverEntry().

◆ AhciHwPassiveInitialize()

BOOLEAN NTAPI AhciHwPassiveInitialize ( __in PVOID  DeviceExtension)

Definition at line 485 of file storahci.c.

488{
489 ULONG index;
490 PAHCI_ADAPTER_EXTENSION AdapterExtension;
491 PAHCI_PORT_EXTENSION PortExtension;
492
493 AhciDebugPrint("AhciHwPassiveInitialize()\n");
494
495 AdapterExtension = (PAHCI_ADAPTER_EXTENSION)DeviceExtension;
496
497 for (index = 0; index < AdapterExtension->PortCount; index++)
498 {
499 if ((AdapterExtension->PortImplemented & (0x1 << index)) != 0)
500 {
501 PortExtension = &AdapterExtension->PortExtension[index];
502 PortExtension->DeviceParams.IsActive = AhciStartPort(PortExtension);
504 }
505 }
506
507 return TRUE;
508}// -- AhciHwPassiveInitialize();
VOID NTAPI AhciCommandCompletionDpcRoutine(__in PSTOR_DPC Dpc, __in PVOID HwDeviceExtension, __in PVOID SystemArgument1, __in PVOID SystemArgument2)
Definition: storahci.c:422
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:7904
STOR_DPC CommandCompletion
Definition: storahci.h:484

Referenced by AhciHwInitialize().

◆ AhciHwResetBus()

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

Definition at line 932 of file storahci.c.

936{
937 STOR_LOCK_HANDLE lockhandle = {0};
938// PAHCI_ADAPTER_EXTENSION adapterExtension;
939
940 AhciDebugPrint("AhciHwResetBus()\n");
941
942// adapterExtension = AdapterExtension;
943
944 if (IsPortValid(AdapterExtension, PathId))
945 {
946 // Acquire Lock
947 StorPortAcquireSpinLock(AdapterExtension, InterruptLock, NULL, &lockhandle);
948
949 // TODO: Perform port reset
950
951 // Release lock
952 StorPortReleaseSpinLock(AdapterExtension, &lockhandle);
953 }
954
955 return FALSE;
956}// -- 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 789 of file storahci.c.

793{
794 PAHCI_ADAPTER_EXTENSION AdapterExtension;
795
796 AhciDebugPrint("AhciHwStartIo()\n");
797
798 AdapterExtension = (PAHCI_ADAPTER_EXTENSION)DeviceExtension;
799
800 if (!IsPortValid(AdapterExtension, Srb->PathId))
801 {
803 StorPortNotification(RequestComplete, AdapterExtension, Srb);
804 return TRUE;
805 }
806
807 switch(Srb->Function)
808 {
809 case SRB_FUNCTION_PNP:
810 {
811 // https://learn.microsoft.com/en-us/previous-versions/windows/drivers/storage/handling-srb-function-pnp
812 // If the function member of an SRB is set to SRB_FUNCTION_PNP,
813 // the SRB is a structure of type SCSI_PNP_REQUEST_BLOCK.
814
815 PSCSI_PNP_REQUEST_BLOCK pnpRequest;
816 pnpRequest = (PSCSI_PNP_REQUEST_BLOCK)Srb;
817 if ((pnpRequest->SrbPnPFlags & SRB_PNP_FLAGS_ADAPTER_REQUEST) != 0)
818 {
819 switch(pnpRequest->PnPAction)
820 {
821 case StorRemoveDevice:
823 {
825 AdapterExtension->StateFlags.Removed = 1;
826 AhciDebugPrint("\tAdapter removed\n");
827 }
828 break;
829 case StorStopDevice:
830 {
832 AhciDebugPrint("\tRequested to Stop the adapter\n");
833 }
834 break;
835 default:
837 break;
838 }
839 }
840 else
841 {
843 }
844 }
845 break;
847 {
848 // https://learn.microsoft.com/en-us/previous-versions/windows/drivers/storage/handling-srb-function-execute-scsi
849 // On receipt of an SRB_FUNCTION_EXECUTE_SCSI request, a miniport driver's HwScsiStartIo
850 // routine does the following:
851 //
852 // - Gets and/or sets up whatever context the miniport driver maintains in its device,
853 // logical unit, and/or SRB extensions
854 // For example, a miniport driver might set up a logical unit extension with pointers
855 // to the SRB itself and the SRB DataBuffer pointer, the SRB DataTransferLength value,
856 // and a driver-defined value (or CDB SCSIOP_XXX value) indicating the operation to be
857 // carried out on the HBA.
858 //
859 // - Calls an internal routine to program the HBA, as partially directed by the SrbFlags,
860 // for the requested operation
861 // For a device I/O operation, such an internal routine generally selects the target device
862 // and sends the CDB over the bus to the target logical unit.
863 PCDB cdb = (PCDB)&Srb->Cdb;
864 if (Srb->CdbLength == 0)
865 {
866 AhciDebugPrint("\tOperationCode: %d\n", cdb->CDB10.OperationCode);
868 break;
869 }
870
871 NT_ASSERT(cdb != NULL);
872
873 switch(cdb->CDB10.OperationCode)
874 {
875 case SCSIOP_INQUIRY:
876 Srb->SrbStatus = DeviceInquiryRequest(AdapterExtension, Srb, cdb);
877 break;
879 Srb->SrbStatus = DeviceReportLuns(AdapterExtension, Srb, cdb);
880 break;
882 Srb->SrbStatus = DeviceRequestCapacity(AdapterExtension, Srb, cdb);
883 break;
885 Srb->SrbStatus = DeviceRequestComplete(AdapterExtension, Srb, cdb);
886 break;
888 Srb->SrbStatus = DeviceRequestSense(AdapterExtension, Srb, cdb);
889 break;
890 case SCSIOP_READ:
891 case SCSIOP_WRITE:
892 Srb->SrbStatus = DeviceRequestReadWrite(AdapterExtension, Srb, cdb);
893 break;
894 default:
895 AhciDebugPrint("\tOperationCode: %d\n", cdb->CDB10.OperationCode);
897 break;
898 }
899 }
900 break;
901 default:
902 AhciDebugPrint("\tUnknown function code recieved: %x\n", Srb->Function);
904 break;
905 }
906
908 {
909 StorPortNotification(RequestComplete, AdapterExtension, Srb);
910 }
911 else
912 {
913 AhciProcessIO(AdapterExtension, Srb->PathId, Srb);
914 }
915 return TRUE;
916}// -- 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:2198
UCHAR DeviceInquiryRequest(__in PAHCI_ADAPTER_EXTENSION AdapterExtension, __in PSCSI_REQUEST_BLOCK Srb, __in PCDB Cdb)
Definition: storahci.c:2252
UCHAR DeviceRequestSense(__in PAHCI_ADAPTER_EXTENSION AdapterExtension, __in PSCSI_REQUEST_BLOCK Srb, __in PCDB Cdb)
Definition: storahci.c:1935
UCHAR DeviceRequestReadWrite(__in PAHCI_ADAPTER_EXTENSION AdapterExtension, __in PSCSI_REQUEST_BLOCK Srb, __in PCDB Cdb)
Definition: storahci.c:1990
VOID AhciProcessIO(__in PAHCI_ADAPTER_EXTENSION AdapterExtension, __in UCHAR PathId, __in PSCSI_REQUEST_BLOCK Srb)
Definition: storahci.c:1557
UCHAR DeviceRequestCapacity(__in PAHCI_ADAPTER_EXTENSION AdapterExtension, __in PSCSI_REQUEST_BLOCK Srb, __in PCDB Cdb)
Definition: storahci.c:2100
@ 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 623 of file storahci.c.

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

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:1214
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 1557 of file storahci.c.

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

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

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::@1580::_STS STS

Referenced by AhciHwPassiveInitialize().

◆ AhciZeroMemory()

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

Definition at line 2445 of file storahci.c.

2449{
2450 ULONG i;
2451 for (i = 0; i < BufferSize; i++)
2452 {
2453 Buffer[i] = 0;
2454 }
2455
2456 return;
2457}// -- 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 1640 of file storahci.c.

1644{
1645 PAHCI_PORT_EXTENSION PortExtension;
1646 PAHCI_ADAPTER_EXTENSION AdapterExtension;
1649
1650 AhciDebugPrint("AtapiInquiryCompletion()\n");
1651
1652 PortExtension = (PAHCI_PORT_EXTENSION)_Extension;
1653 Srb = (PSCSI_REQUEST_BLOCK)_Srb;
1654
1655 NT_ASSERT(Srb != NULL);
1656 NT_ASSERT(PortExtension != NULL);
1657
1658 AdapterExtension = PortExtension->AdapterExtension;
1659
1660 // send queue depth
1662 Srb->PathId,
1663 Srb->TargetId,
1664 Srb->Lun,
1665 AHCI_Global_Port_CAP_NCS(AdapterExtension->CAP));
1666
1667 NT_ASSERT(status == TRUE);
1668 return;
1669}// -- AtapiInquiryCompletion();
unsigned char BOOLEAN
Definition: actypes.h:127
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:1930
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 2252 of file storahci.c.

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

2203{
2204 PLUN_LIST LunList;
2205 PAHCI_PORT_EXTENSION PortExtension;
2206
2207 AhciDebugPrint("DeviceReportLuns()\n");
2208
2210
2211 PortExtension = &AdapterExtension->PortExtension[Srb->PathId];
2212
2214 NT_ASSERT(Cdb->CDB10.OperationCode == SCSIOP_REPORT_LUNS);
2215
2216 if (PortExtension->DeviceParams.DeviceType == AHCI_DEVICE_TYPE_ATAPI)
2217 {
2218 return AhciATAPICommand(AdapterExtension, Srb, Cdb);
2219 }
2220
2221 LunList = (PLUN_LIST)Srb->DataBuffer;
2222
2223 NT_ASSERT(LunList != NULL);
2224
2225 AhciZeroMemory((PCHAR)LunList, sizeof(LUN_LIST));
2226
2227 LunList->LunListLength[3] = 8;
2228
2230 Srb->DataTransferLength = sizeof(LUN_LIST);
2231
2232 return SRB_STATUS_SUCCESS;
2233}// -- 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 2100 of file storahci.c.

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

2173{
2174 AhciDebugPrint("DeviceRequestComplete()\n");
2175
2176 UNREFERENCED_PARAMETER(AdapterExtension);
2178
2180
2181 return SRB_STATUS_SUCCESS;
2182}// -- DeviceRequestComplete();

◆ DeviceRequestReadWrite()

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

Definition at line 1990 of file storahci.c.

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

1940{
1941 PMODE_PARAMETER_HEADER ModeHeader;
1942 PAHCI_PORT_EXTENSION PortExtension;
1943
1944 AhciDebugPrint("DeviceRequestSense()\n");
1945
1946 NT_ASSERT(IsPortValid(AdapterExtension, Srb->PathId));
1947 NT_ASSERT(Cdb->CDB10.OperationCode == SCSIOP_MODE_SENSE);
1948
1949 PortExtension = &AdapterExtension->PortExtension[Srb->PathId];
1950
1951 if (PortExtension->DeviceParams.DeviceType == AHCI_DEVICE_TYPE_ATAPI)
1952 {
1953 return AhciATAPICommand(AdapterExtension, Srb, Cdb);
1954 }
1955
1956 ModeHeader = (PMODE_PARAMETER_HEADER)Srb->DataBuffer;
1957
1958 NT_ASSERT(ModeHeader != NULL);
1959
1961
1962 ModeHeader->ModeDataLength = sizeof(MODE_PARAMETER_HEADER);
1963 ModeHeader->MediumType = 0;
1964 ModeHeader->DeviceSpecificParameter = 0;
1965 ModeHeader->BlockDescriptorLength = 0;
1966
1967 if (Cdb->MODE_SENSE.PageCode == MODE_SENSE_CURRENT_VALUES)
1968 {
1969 ModeHeader->ModeDataLength = sizeof(MODE_PARAMETER_HEADER) + sizeof(MODE_PARAMETER_BLOCK);
1970 ModeHeader->BlockDescriptorLength = sizeof(MODE_PARAMETER_BLOCK);
1971 }
1972
1973 return SRB_STATUS_SUCCESS;
1974}// -- 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 1165 of file storahci.c.

1169{
1170 ULONG status;
1171 // initialize the hardware data structure
1172 HW_INITIALIZATION_DATA hwInitializationData = {0};
1173
1174 // set size of hardware initialization structure
1175 hwInitializationData.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);
1176
1177 // identity required miniport entry point routines
1178 hwInitializationData.HwStartIo = AhciHwStartIo;
1179 hwInitializationData.HwResetBus = AhciHwResetBus;
1180 hwInitializationData.HwInterrupt = AhciHwInterrupt;
1181 hwInitializationData.HwInitialize = AhciHwInitialize;
1182 hwInitializationData.HwFindAdapter = AhciHwFindAdapter;
1183
1184 // adapter specific information
1185 hwInitializationData.TaggedQueuing = TRUE;
1186 hwInitializationData.AutoRequestSense = TRUE;
1187 hwInitializationData.MultipleRequestPerLu = TRUE;
1188 hwInitializationData.NeedPhysicalAddresses = TRUE;
1189
1190 hwInitializationData.NumberOfAccessRanges = 6;
1191 hwInitializationData.AdapterInterfaceType = PCIBus;
1192 hwInitializationData.MapBuffers = STOR_MAP_NON_READ_WRITE_BUFFERS;
1193
1194 // set required extension sizes
1195 hwInitializationData.SrbExtensionSize = sizeof(AHCI_SRB_EXTENSION);
1196 hwInitializationData.DeviceExtensionSize = sizeof(AHCI_ADAPTER_EXTENSION);
1197
1198 // register our hw init data
1201 &hwInitializationData,
1202 NULL);
1203
1205 return status;
1206}// -- DriverEntry();
struct _HW_INITIALIZATION_DATA HW_INITIALIZATION_DATA
@ PCIBus
Definition: restypes.h:127
#define STATUS_SUCCESS
Definition: shellext.h:65
BOOLEAN NTAPI AhciHwInterrupt(__in PVOID DeviceExtension)
Definition: storahci.c:721
BOOLEAN NTAPI AhciHwStartIo(__in PVOID DeviceExtension, __in PSCSI_REQUEST_BLOCK Srb)
Definition: storahci.c:789
BOOLEAN NTAPI AhciHwResetBus(__in PVOID AdapterExtension, __in ULONG PathId)
Definition: storahci.c:932
BOOLEAN NTAPI AhciHwInitialize(__in PVOID DeviceExtension)
Definition: storahci.c:523
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:992
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:1401
#define STOR_MAP_NON_READ_WRITE_BUFFERS
Definition: storport.h:562
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 2566 of file storahci.c.

2569{
2570 ULONG Offset;
2571 ULONG_PTR SrbExtension;
2572
2573 SrbExtension = (ULONG_PTR)Srb->SrbExtension;
2574 Offset = SrbExtension % 128;
2575
2576 // CommandTable should be 128 byte aligned
2577 if (Offset != 0)
2578 Offset = 128 - Offset;
2579
2580 return (PAHCI_SRB_EXTENSION)(SrbExtension + Offset);
2581}// -- 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 1683 of file storahci.c.

1687{
1688 PAHCI_PORT_EXTENSION PortExtension;
1690
1691// PCDB cdb;
1693 PINQUIRYDATA InquiryData;
1694 PAHCI_SRB_EXTENSION SrbExtension;
1695 PAHCI_ADAPTER_EXTENSION AdapterExtension;
1696 PIDENTIFY_DEVICE_DATA IdentifyDeviceData;
1697
1698 AhciDebugPrint("InquiryCompletion()\n");
1699
1700 PortExtension = (PAHCI_PORT_EXTENSION)_Extension;
1701 Srb = (PSCSI_REQUEST_BLOCK)_Srb;
1702
1703 NT_ASSERT(Srb != NULL);
1704 NT_ASSERT(PortExtension != NULL);
1705
1706// cdb = (PCDB)&Srb->Cdb;
1707 InquiryData = Srb->DataBuffer;
1708 SrbExtension = GetSrbExtension(Srb);
1709 AdapterExtension = PortExtension->AdapterExtension;
1710 IdentifyDeviceData = PortExtension->IdentifyDeviceData;
1711
1713 {
1715 {
1716 PortExtension->DeviceParams.DeviceType = AHCI_DEVICE_TYPE_NODEVICE;
1717 }
1718 return;
1719 }
1720
1721 NT_ASSERT(InquiryData != NULL);
1723
1724 // Device specific data
1725 PortExtension->DeviceParams.MaxLba.QuadPart = 0;
1726
1727 if (SrbExtension->CommandReg == IDE_COMMAND_IDENTIFY)
1728 {
1729 PortExtension->DeviceParams.DeviceType = AHCI_DEVICE_TYPE_ATA;
1730 if (IdentifyDeviceData->GeneralConfiguration.RemovableMedia)
1731 {
1732 PortExtension->DeviceParams.RemovableDevice = 1;
1733 }
1734
1735 if ((IdentifyDeviceData->CommandSetSupport.BigLba) && (IdentifyDeviceData->CommandSetActive.BigLba))
1736 {
1737 PortExtension->DeviceParams.Lba48BitMode = 1;
1738 }
1739
1740 PortExtension->DeviceParams.AccessType = DIRECT_ACCESS_DEVICE;
1741
1742 /* Device max address lba */
1743 if (PortExtension->DeviceParams.Lba48BitMode)
1744 {
1745 PortExtension->DeviceParams.MaxLba.LowPart = IdentifyDeviceData->Max48BitLBA[0];
1746 PortExtension->DeviceParams.MaxLba.HighPart = IdentifyDeviceData->Max48BitLBA[1];
1747 }
1748 else
1749 {
1750 PortExtension->DeviceParams.MaxLba.LowPart = IdentifyDeviceData->UserAddressableSectors;
1751 }
1752
1753 /* Bytes Per Logical Sector */
1754 if (IdentifyDeviceData->PhysicalLogicalSectorSize.LogicalSectorLongerThan256Words)
1755 {
1756 AhciDebugPrint("\tBytesPerLogicalSector != DEVICE_ATA_BLOCK_SIZE\n");
1758 }
1759
1760 PortExtension->DeviceParams.BytesPerLogicalSector = DEVICE_ATA_BLOCK_SIZE;
1761
1762 /* Bytes Per Physical Sector */
1763 if (IdentifyDeviceData->PhysicalLogicalSectorSize.MultipleLogicalSectorsPerPhysicalSector)
1764 {
1765 AhciDebugPrint("\tBytesPerPhysicalSector != DEVICE_ATA_BLOCK_SIZE\n");
1767 }
1768
1769 PortExtension->DeviceParams.BytesPerPhysicalSector = DEVICE_ATA_BLOCK_SIZE;
1770
1771 // last byte should be NULL
1772 StorPortCopyMemory(PortExtension->DeviceParams.VendorId, IdentifyDeviceData->ModelNumber, sizeof(PortExtension->DeviceParams.VendorId) - 1);
1773 StorPortCopyMemory(PortExtension->DeviceParams.RevisionID, IdentifyDeviceData->FirmwareRevision, sizeof(PortExtension->DeviceParams.RevisionID) - 1);
1774 StorPortCopyMemory(PortExtension->DeviceParams.SerialNumber, IdentifyDeviceData->SerialNumber, sizeof(PortExtension->DeviceParams.SerialNumber) - 1);
1775
1776 PortExtension->DeviceParams.VendorId[sizeof(PortExtension->DeviceParams.VendorId) - 1] = '\0';
1777 PortExtension->DeviceParams.RevisionID[sizeof(PortExtension->DeviceParams.RevisionID) - 1] = '\0';
1778 PortExtension->DeviceParams.SerialNumber[sizeof(PortExtension->DeviceParams.SerialNumber) - 1] = '\0';
1779
1780 // TODO: Add other device params
1781 AhciDebugPrint("\tATA Device\n");
1782 }
1783 else
1784 {
1785 AhciDebugPrint("\tATAPI Device\n");
1786 PortExtension->DeviceParams.DeviceType = AHCI_DEVICE_TYPE_ATAPI;
1787 PortExtension->DeviceParams.AccessType = READ_ONLY_DIRECT_ACCESS_DEVICE;
1788 }
1789
1790 // INQUIRYDATABUFFERSIZE = 36 ; Defined in storport.h
1792 {
1793 AhciDebugPrint("\tDataBufferLength < sizeof(INQUIRYDATA), Could crash the driver.\n");
1795 }
1796
1797 // update data transfer length
1799
1800 // prepare data to send
1801 InquiryData->Versions = 2;
1802 InquiryData->Wide32Bit = 1;
1803 InquiryData->CommandQueue = 0; // NCQ not supported
1804 InquiryData->ResponseDataFormat = 0x2;
1805 InquiryData->DeviceTypeModifier = 0;
1807 InquiryData->AdditionalLength = INQUIRYDATABUFFERSIZE - 5;
1808 InquiryData->DeviceType = PortExtension->DeviceParams.AccessType;
1809 InquiryData->RemovableMedia = PortExtension->DeviceParams.RemovableDevice;
1810
1811 // Fill VendorID, Product Revision Level and other string fields
1812 StorPortCopyMemory(InquiryData->VendorId, PortExtension->DeviceParams.VendorId, sizeof(InquiryData->VendorId) - 1);
1813 StorPortCopyMemory(InquiryData->ProductId, PortExtension->DeviceParams.RevisionID, sizeof(PortExtension->DeviceParams.RevisionID));
1814 StorPortCopyMemory(InquiryData->ProductRevisionLevel, PortExtension->DeviceParams.SerialNumber, sizeof(InquiryData->ProductRevisionLevel) - 1);
1815
1816 InquiryData->VendorId[sizeof(InquiryData->VendorId) - 1] = '\0';
1817 InquiryData->ProductId[sizeof(InquiryData->ProductId) - 1] = '\0';
1818 InquiryData->ProductRevisionLevel[sizeof(InquiryData->ProductRevisionLevel) - 1] = '\0';
1819
1820 // send queue depth
1822 Srb->PathId,
1823 Srb->TargetId,
1824 Srb->Lun,
1825 AHCI_Global_Port_CAP_NCS(AdapterExtension->CAP));
1826
1827 NT_ASSERT(status == TRUE);
1828 return;
1829}// -- 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:7387
UCHAR FirmwareRevision[8]
Definition: ata.h:25
struct _IDENTIFY_DEVICE_DATA::@2208 CommandSetSupport
ULONG Max48BitLBA[2]
Definition: ata.h:255
struct _IDENTIFY_DEVICE_DATA::@2209 CommandSetActive
UCHAR ModelNumber[40]
Definition: ata.h:26
struct _IDENTIFY_DEVICE_DATA::@2212 PhysicalLogicalSectorSize
UCHAR SerialNumber[20]
Definition: ata.h:22
struct _IDENTIFY_DEVICE_DATA::@2201 GeneralConfiguration
ULONG UserAddressableSectors
Definition: ata.h:60
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 2473 of file storahci.c.

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

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

◆ RemoveQueue()

FORCEINLINE PVOID RemoveQueue ( __inout PAHCI_QUEUE  Queue)

Definition at line 2534 of file storahci.c.

2537{
2538 PVOID Srb;
2539
2542
2543 if (Queue->Head == Queue->Tail)
2544 return NULL;
2545
2546 Srb = Queue->Buffer[Queue->Tail++];
2548
2549 return Srb;
2550}// -- RemoveQueue();

Referenced by AhciCommandCompletionDpcRoutine(), and AhciProcessIO().