ReactOS 0.4.16-dev-2633-g8dc9e50
portstate.c File Reference
#include "atapi.h"
Include dependency graph for portstate.c:

Go to the source code of this file.

Functions

static VOID AtaPortQueueEvent (_In_ PATAPORT_PORT_DATA PortData, _In_opt_ PATAPORT_DEVICE_EXTENSION DevExt, _In_opt_ PATA_DEVICE_REQUEST FailedRequest, _In_ ATA_PORT_ACTION Action)
 
static ATA_PORT_ACTION AtaPortClearPortAction (_In_ PATA_WORKER_CONTEXT Context, _In_ ATA_PORT_ACTION Action)
 
static BOOLEAN AtaPortClearDeviceAction (_In_ PATAPORT_DEVICE_EXTENSION DevExt, _In_ ATA_PORT_ACTION Action)
 
static PATAPORT_DEVICE_EXTENSION AtaPortFindDeviceForAction (_In_ PATAPORT_PORT_DATA PortData, _In_ ATA_PORT_ACTION Action)
 
static VOID AtaPortOnAsyncNotification (_In_ PATAPORT_PORT_DATA PortData, _In_ ULONG DeviceBitmap)
 
static VOID AtaPortOnResetNotification (_In_ PATAPORT_PORT_DATA PortData, _In_ ULONG DeviceBitmap)
 
static VOID AtaPortOnRequestComplete (_In_ PATAPORT_PORT_DATA PortData, _In_ ULONG CommandsCompleted)
 
static VOID AtaPortMarkDeviceFailed (_In_ PATAPORT_PORT_DATA PortData, _In_ PATAPORT_DEVICE_EXTENSION DevExt)
 
static NTSTATUS AtaPortEnumeratePort (_In_ PATAPORT_PORT_DATA PortData)
 
static NTSTATUS AtaPortResetPort (_In_ PATAPORT_PORT_DATA PortData)
 
static NTSTATUS AtaPortEnumerateDevice (_In_ PATAPORT_PORT_DATA PortData, _In_ ATA_PORT_ACTION Action)
 
static NTSTATUS AtaPortRecoveryFromError (_In_ PATAPORT_PORT_DATA PortData)
 
static NTSTATUS AtaPortConfigureDevice (_In_ PATAPORT_PORT_DATA PortData)
 
static NTSTATUS AtaPortDeviceChangePower (_In_ PATAPORT_PORT_DATA PortData)
 
static NTSTATUS AtaPortSetTransferMode (_In_ PATAPORT_PORT_DATA PortData)
 
static BOOLEAN AtaPortGetNextEvent (_In_ PATAPORT_PORT_DATA PortData, _Out_ ATA_PORT_ACTION *Action)
 
static VOID AtaPortRunStateMachine (_In_ PATAPORT_PORT_DATA PortData)
 
static VOID AtaPortWaitForIdle (_In_ PATAPORT_PORT_DATA PortData)
 
static VOID AtaPortEnterStateMachine (_In_ PATAPORT_PORT_DATA PortData)
 
static VOID AtaPortExitStateMachine (_In_ PATAPORT_PORT_DATA PortData)
 
static VOID AtaPortWorkerClearSignal (_In_ PATAPORT_PORT_DATA PortData)
 
VOID NTAPI AtaPortWorkerThread (_In_ PVOID StartContext)
 
VOID __cdecl AtaPortNotification (_In_ PORT_NOTIFICATION_TYPE NotificationType, _In_ PVOID PortContext,...)
 
ATA_COMPLETION_ACTION AtaPortCompleteInternalRequest (_In_ PATA_DEVICE_REQUEST Request)
 
NTSTATUS AtaPortSendRequest (_In_ PATAPORT_PORT_DATA PortData, _In_ PATAPORT_DEVICE_EXTENSION DevExt)
 
VOID AtaPortTimeout (_In_ PATAPORT_PORT_DATA PortData, _In_ ULONG Slot)
 
DECLSPEC_NOINLINE_FROM_PAGED VOID AtaPortSignalWorkerThread (_In_ PATAPORT_PORT_DATA PortData)
 
VOID NTAPI AtaPortWorkerSignalDpc (_In_ PKDPC Dpc, _In_opt_ PVOID DeferredContext, _In_opt_ PVOID SystemArgument1, _In_opt_ PVOID SystemArgument2)
 
DECLSPEC_NOINLINE_FROM_PAGED VOID AtaDeviceQueueEvent (_In_ PATAPORT_PORT_DATA PortData, _In_opt_ PATAPORT_DEVICE_EXTENSION DevExt, _In_ ATA_PORT_ACTION Action)
 

Function Documentation

◆ AtaDeviceQueueEvent()

Definition at line 992 of file portstate.c.

996{
998
999 TRACE("New action %lu\n", Action);
1000
1001 OldIrql = KeAcquireInterruptSpinLock(PortData->InterruptObject);
1002 AtaPortQueueEvent(PortData, DevExt, NULL, Action);
1003 KeReleaseInterruptSpinLock(PortData->InterruptObject, OldIrql);
1004}
#define NULL
Definition: types.h:112
UCHAR KIRQL
Definition: env_spec_w32.h:591
KIRQL NTAPI KeAcquireInterruptSpinLock(IN PKINTERRUPT Interrupt)
Definition: spinlock.c:154
VOID NTAPI KeReleaseInterruptSpinLock(IN PKINTERRUPT Interrupt, IN KIRQL OldIrql)
Definition: spinlock.c:171
static VOID AtaPortQueueEvent(_In_ PATAPORT_PORT_DATA PortData, _In_opt_ PATAPORT_DEVICE_EXTENSION DevExt, _In_opt_ PATA_DEVICE_REQUEST FailedRequest, _In_ ATA_PORT_ACTION Action)
Definition: portstate.c:16
#define TRACE(s)
Definition: solgame.cpp:4
_In_ WDFIOTARGET _In_ _Strict_type_match_ WDF_IO_TARGET_SENT_IO_ACTION Action
Definition: wdfiotarget.h:510
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778

Referenced by AtaFdoEnumeratePort(), AtaFdoQueryDeviceCount(), AtaFdoQueryDeviceStatus(), AtaPdoQueuePowerIrp(), and AtaPdoStartDevice().

◆ AtaPortClearDeviceAction()

static BOOLEAN AtaPortClearDeviceAction ( _In_ PATAPORT_DEVICE_EXTENSION  DevExt,
_In_ ATA_PORT_ACTION  Action 
)
static

Definition at line 98 of file portstate.c.

101{
102 TRACE("Clear dev action %lx, total %lx\n", Action, DevExt->Worker.EventsPending & ~Action);
103
104 return !!(_InterlockedAnd(&DevExt->Worker.EventsPending, ~(ULONG)Action) & Action);
105}
volatile char *const const char modify _InterlockedAnd
Definition: intrin_ppc.h:267
uint32_t ULONG
Definition: typedefs.h:59

Referenced by AtaPortConfigureDevice(), AtaPortDeviceChangePower(), AtaPortEnumerateDevice(), and AtaPortRecoveryFromError().

◆ AtaPortClearPortAction()

static ATA_PORT_ACTION AtaPortClearPortAction ( _In_ PATA_WORKER_CONTEXT  Context,
_In_ ATA_PORT_ACTION  Action 
)
static

Definition at line 87 of file portstate.c.

90{
91 TRACE("Clear port action %lx, total %lx\n", Action, Context->EventsPending & ~Action);
92
93 return _InterlockedAnd(&Context->EventsPending, ~(ULONG)Action);
94}
_In_ PVOID Context
Definition: storport.h:2269

Referenced by AtaPortEnumerateDevice(), AtaPortEnumeratePort(), AtaPortFindDeviceForAction(), AtaPortResetPort(), and AtaPortSetTransferMode().

◆ AtaPortCompleteInternalRequest()

ATA_COMPLETION_ACTION AtaPortCompleteInternalRequest ( _In_ PATA_DEVICE_REQUEST  Request)

Definition at line 818 of file portstate.c.

820{
822 PATAPORT_PORT_DATA PortData = Device->PortData;
823
825 KeSetEvent(&PortData->Worker.CompletionEvent, IO_NO_INCREMENT, FALSE);
826
827 return COMPLETE_IRP;
828}
@ COMPLETE_IRP
Definition: ata_shared.h:149
#define REQUEST_FLAG_INTERNAL
Definition: ata_shared.h:345
struct _ATAPORT_IO_CONTEXT * PATAPORT_IO_CONTEXT
Definition: atapi.h:36
#define FALSE
Definition: types.h:117
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define ASSERT(a)
Definition: mode.c:44
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
#define IO_NO_INCREMENT
Definition: iotypes.h:598

◆ AtaPortConfigureDevice()

static NTSTATUS AtaPortConfigureDevice ( _In_ PATAPORT_PORT_DATA  PortData)
static

Definition at line 399 of file portstate.c.

401{
404
406 if (!DevExt)
407 return STATUS_SUCCESS;
408
409 Status = AtaPortDeviceProcessConfig(PortData, DevExt);
411 {
412 AtaPortMarkDeviceFailed(PortData, DevExt);
413 return Status;
414 }
415
418
419 return STATUS_SUCCESS;
420}
@ ACTION_DEVICE_CONFIG
Definition: atapi.h:248
NTSTATUS AtaPortDeviceProcessConfig(_In_ PATAPORT_PORT_DATA PortData, _In_ PATAPORT_DEVICE_EXTENSION DevExt)
Definition: dev_config.c:341
LONG NTSTATUS
Definition: precomp.h:26
Status
Definition: gdiplustypes.h:25
#define STATUS_ADAPTER_HARDWARE_ERROR
Definition: ntstatus.h:524
static PATAPORT_DEVICE_EXTENSION AtaPortFindDeviceForAction(_In_ PATAPORT_PORT_DATA PortData, _In_ ATA_PORT_ACTION Action)
Definition: portstate.c:109
static BOOLEAN AtaPortClearDeviceAction(_In_ PATAPORT_DEVICE_EXTENSION DevExt, _In_ ATA_PORT_ACTION Action)
Definition: portstate.c:98
static VOID AtaPortMarkDeviceFailed(_In_ PATAPORT_PORT_DATA PortData, _In_ PATAPORT_DEVICE_EXTENSION DevExt)
Definition: portstate.c:236
#define STATUS_SUCCESS
Definition: shellext.h:65
ATA_WORKER_DEVICE_CONTEXT Worker
Definition: atapi.h:458

Referenced by AtaPortRunStateMachine().

◆ AtaPortDeviceChangePower()

static NTSTATUS AtaPortDeviceChangePower ( _In_ PATAPORT_PORT_DATA  PortData)
static

Definition at line 424 of file portstate.c.

426{
429
431 if (!DevExt)
432 return STATUS_SUCCESS;
433
434 Status = AtaPortDeviceProcessPowerChange(PortData, DevExt);
436 {
437 AtaPortMarkDeviceFailed(PortData, DevExt);
438 return Status;
439 }
440
442 return STATUS_SUCCESS;
443}
@ ACTION_DEVICE_POWER
Definition: atapi.h:250
NTSTATUS AtaPortDeviceProcessPowerChange(_In_ PATAPORT_PORT_DATA PortData, _In_ PATAPORT_DEVICE_EXTENSION DevExt)
Definition: dev_power.c:151

Referenced by AtaPortRunStateMachine().

◆ AtaPortEnterStateMachine()

static VOID AtaPortEnterStateMachine ( _In_ PATAPORT_PORT_DATA  PortData)
static

Definition at line 591 of file portstate.c.

593{
595 ATA_SCSI_ADDRESS AtaScsiAddress;
596
597 ChanExt = CONTAINING_RECORD(PortData, ATAPORT_CHANNEL_EXTENSION, PortData);
598 ASSERT(IS_FDO(ChanExt));
599
600 AtaScsiAddress.AsULONG = 0;
601 while (TRUE)
602 {
604 PULONG PowerIdleCounter;
605
606 /*
607 * Acquire a reference to make sure the device object is valid
608 * for the duration of the port event handling.
609 */
610 DevExt = AtaFdoFindNextDeviceByPath(ChanExt,
611 &AtaScsiAddress,
612 FALSE,
614 if (!DevExt)
615 break;
616
618 DevExt->Worker.ResetRetryCount = 0;
619
621 {
623 continue;
624 }
625
626 /* Stop the Srb processing */
628
629 /*
630 * There is a chance that we can receive a power down request
631 * while the state maching is being running, so mark the device as busy
632 * to reduce the request probability.
633 */
634 PowerIdleCounter = DevExt->Device.PowerIdleCounter;
635 if (PowerIdleCounter)
636 PoSetDeviceBusy(PowerIdleCounter);
637 }
638
639 /* Wait for the port queue to become empty */
640 AtaPortWaitForIdle(PortData);
641
642 PortData->Worker.Flags = 0;
643 PortData->Worker.BadDeviceBitmap = 0;
644 PortData->Worker.ResetRetryCount = 0;
645#if DBG
646 PortData->Worker.StateLoopCount = 0;
647#endif
648
649 // FIXME: Handle PORT_FLAG_IS_SIMPLEX
650}
#define DEV_WORKER_FLAG_HOLD_REFERENCE
Definition: atapi.h:304
KSTART_ROUTINE AtaPortWorkerThread
Definition: atapi.h:878
#define IS_FDO(p)
Definition: atapi.h:173
#define QUEUE_FLAG_FROZEN_PORT_BUSY
Definition: atapi.h:105
DECLSPEC_NOINLINE_FROM_PAGED PATAPORT_DEVICE_EXTENSION AtaFdoFindNextDeviceByPath(_In_ PATAPORT_CHANNEL_EXTENSION ChanExt, _Inout_ PATA_SCSI_ADDRESS AtaScsiAddress, _In_ BOOLEAN SearchRemoveDev, _In_ PVOID ReferenceTag)
Definition: fdo.c:654
#define DEV_WORKER_FLAG_REMOVED
Definition: atapi.h:305
DECLSPEC_NOINLINE_FROM_PAGED VOID AtaReqFreezeQueue(_In_ PATAPORT_DEVICE_EXTENSION DevExt, _In_ ULONG ReasonFlags)
Definition: scsi.c:1351
#define QUEUE_FLAG_FROZEN_REMOVED
Definition: atapi.h:111
#define TRUE
Definition: types.h:120
static VOID AtaPortWaitForIdle(_In_ PATAPORT_PORT_DATA PortData)
Definition: portstate.c:569
ATAPORT_IO_CONTEXT Device
Definition: atapi.h:457
PULONG PowerIdleCounter
Definition: atapi.h:98
uint32_t * PULONG
Definition: typedefs.h:59
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
ULONG AsULONG
Definition: atapi.h:69
#define PoSetDeviceBusy(IdlePointer)

Referenced by AtaPortWorkerThread().

◆ AtaPortEnumerateDevice()

static NTSTATUS AtaPortEnumerateDevice ( _In_ PATAPORT_PORT_DATA  PortData,
_In_ ATA_PORT_ACTION  Action 
)
static

Definition at line 324 of file portstate.c.

327{
329
331 {
332 DevExt = PortData->Worker.EnumDevExt;
333 ASSERT(DevExt);
335 }
336 else
337 {
338 DevExt = AtaPortFindDeviceForAction(PortData, Action);
339 if (!DevExt)
340 return STATUS_SUCCESS;
341 }
342
343 if (PortData->Worker.BadDeviceBitmap & (1 << (ULONG)DevExt->Device.AtaScsiAddress.TargetId))
344 {
346 }
347 else
348 {
349 DevExt->Worker.EnumStatus = AtaPortIdentifyDevice(PortData, DevExt);
350 if (DevExt->Worker.EnumStatus == DEV_STATUS_FAILED)
351 {
352 AtaPortMarkDeviceFailed(PortData, DevExt);
354 }
355 }
356
357 if ((DevExt->Worker.EnumStatus != DEV_STATUS_SAME_DEVICE) &&
359 {
361 }
362
363 if (AtaPortClearDeviceAction(DevExt, Action))
364 {
366 AtaPortClearPortAction(&PortData->Worker, Action);
367
369 }
370
371 return STATUS_SUCCESS;
372}
@ ACTION_ENUM_DEVICE_NEW
Definition: atapi.h:245
@ DEV_STATUS_FAILED
Definition: atapi.h:258
@ DEV_STATUS_SAME_DEVICE
Definition: atapi.h:257
@ DEV_STATUS_NO_DEVICE
Definition: atapi.h:255
#define DEVICE_UNINITIALIZED
Definition: atapi.h:91
ATA_DEVICE_STATUS AtaPortIdentifyDevice(_In_ PATAPORT_PORT_DATA PortData, _In_ PATAPORT_DEVICE_EXTENSION DevExt)
Definition: dev_identify.c:213
static ATA_PORT_ACTION AtaPortClearPortAction(_In_ PATA_WORKER_CONTEXT Context, _In_ ATA_PORT_ACTION Action)
Definition: portstate.c:87
ULONG DeviceFlags
Definition: atapi.h:81
ATA_SCSI_ADDRESS AtaScsiAddress
Definition: atapi.h:100
volatile LONG EnumStatus
Definition: atapi.h:301
UCHAR TargetId
Definition: atapi.h:60

Referenced by AtaPortRunStateMachine().

◆ AtaPortEnumeratePort()

static NTSTATUS AtaPortEnumeratePort ( _In_ PATAPORT_PORT_DATA  PortData)
static

Definition at line 255 of file portstate.c.

257{
259 ATA_SCSI_ADDRESS AtaScsiAddress;
260
261 _InterlockedOr(&PortData->InterruptFlags, PORT_INT_FLAG_IGNORE_LINK_IRQ);
262 PortData->Worker.DeviceCount = PortData->EnumerateChannel(PortData->ChannelContext);
263 _InterlockedAnd(&PortData->InterruptFlags, ~PORT_INT_FLAG_IGNORE_LINK_IRQ);
264
265 INFO("CH %lu: Detected %lu devices\n", PortData->PortNumber, PortData->Worker.DeviceCount);
266
267 if (AtaPortClearPortAction(&PortData->Worker, ACTION_ENUM_PORT))
268 {
269 /* Defer the completion */
270 PortData->Worker.Flags |= WORKER_FLAG_COMPLETE_PORT_ENUM_EVENT;
271 }
272
273 ChanExt = CONTAINING_RECORD(PortData, ATAPORT_CHANNEL_EXTENSION, PortData);
274
275 /* Remove detached devices */
276 AtaScsiAddress.AsULONG = 0;
277 while (TRUE)
278 {
280
281 DevExt = AtaFdoFindNextDeviceByPath(ChanExt, &AtaScsiAddress, FALSE, NULL);
282 if (!DevExt)
283 break;
284
285 if (AtaScsiAddress.TargetId >= PortData->Worker.DeviceCount)
287 }
288
289 return STATUS_SUCCESS;
290}
@ ACTION_ENUM_PORT
Definition: atapi.h:244
#define PORT_INT_FLAG_IGNORE_LINK_IRQ
Definition: atapi.h:361
#define WORKER_FLAG_COMPLETE_PORT_ENUM_EVENT
Definition: atapi.h:280
#define INFO
Definition: debug.h:89
long _InterlockedOr(_Interlocked_operand_ long volatile *_Value, long _Mask)

Referenced by AtaPortResetPort(), and AtaPortRunStateMachine().

◆ AtaPortExitStateMachine()

static VOID AtaPortExitStateMachine ( _In_ PATAPORT_PORT_DATA  PortData)
static

Definition at line 654 of file portstate.c.

656{
658 ATA_SCSI_ADDRESS AtaScsiAddress;
659
660 ChanExt = CONTAINING_RECORD(PortData, ATAPORT_CHANNEL_EXTENSION, PortData);
661
662 AtaScsiAddress.AsULONG = 0;
663 while (TRUE)
664 {
667
668 DevExt = AtaFdoFindNextDeviceByPath(ChanExt, &AtaScsiAddress, TRUE, NULL);
669 if (!DevExt)
670 break;
671
673 {
675 if (!DevExt->RemovalPending)
676 PortData->Worker.Flags |= WORKER_FLAG_NEED_RESCAN;
677 DevExt->RemovalPending = TRUE;
679
682
685
688 }
689 else
690 {
691 /* Resume the Srb processing */
693 }
694
695 /* Release a reference */
697 {
698 DevExt->Worker.Flags &= ~DEV_WORKER_FLAG_HOLD_REFERENCE;
700 }
701 }
702
703 if (PortData->Worker.Flags & WORKER_FLAG_COMPLETE_PORT_ENUM_EVENT)
704 {
705 /* We defer this event completion to avoid a BusRelations request */
706 PortData->Worker.Flags &= ~WORKER_FLAG_NEED_RESCAN;
707
708 KeSetEvent(&PortData->Worker.EnumerationEvent, 0, FALSE);
709 }
710
711 if (PortData->Worker.Flags & WORKER_FLAG_NEED_RESCAN)
713}
VOID AtaDeviceFlushPowerIrpQueue(_In_ PATAPORT_DEVICE_EXTENSION DevExt)
Definition: dev_power.c:37
#define WORKER_FLAG_NEED_RESCAN
Definition: atapi.h:279
DECLSPEC_NOINLINE_FROM_PAGED VOID AtaReqFlushDeviceQueue(_In_ PATAPORT_IO_CONTEXT Device)
Definition: scsi.c:1451
DECLSPEC_NOINLINE_FROM_PAGED VOID AtaReqThawQueue(_In_ PATAPORT_DEVICE_EXTENSION DevExt, _In_ ULONG ReasonFlags)
Definition: scsi.c:1365
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
VOID NTAPI IoInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
Definition: pnpmgr.c:1772
KSPIN_LOCK PdoListLock
Definition: atapi.h:445
PDEVICE_OBJECT Pdo
Definition: atapi.h:444
IO_REMOVE_LOCK RemoveLock
Definition: atapi.h:434
ATAPORT_COMMON_EXTENSION Common
Definition: atapi.h:455
#define IoReleaseRemoveLock(_RemoveLock, _Tag)
Definition: iofuncs.h:2764
@ BusRelations
Definition: iotypes.h:2154

Referenced by AtaPortWorkerThread().

◆ AtaPortFindDeviceForAction()

static PATAPORT_DEVICE_EXTENSION AtaPortFindDeviceForAction ( _In_ PATAPORT_PORT_DATA  PortData,
_In_ ATA_PORT_ACTION  Action 
)
static

Definition at line 109 of file portstate.c.

112{
116 KIRQL OldIrql, OldLevel;
117
118 ChanExt = CONTAINING_RECORD(PortData, ATAPORT_CHANNEL_EXTENSION, PortData);
119
120 KeAcquireSpinLock(&ChanExt->PdoListLock, &OldLevel);
121 OldIrql = KeAcquireInterruptSpinLock(PortData->InterruptObject);
122
123 for (Entry = ChanExt->PdoList.Next; Entry != NULL; Entry = Entry->Next)
124 {
126
127 if (DevExt->Device.AtaScsiAddress.PathId != PortData->PortNumber)
128 continue;
129
130 if (DevExt->ReportedMissing)
131 continue;
132
134 continue;
135
136 if (DevExt->Worker.EventsPending & Action)
137 {
138 Result = DevExt;
139 break;
140 }
141 }
142
143 if (!Result)
144 AtaPortClearPortAction(&PortData->Worker, Action);
145
146 KeReleaseInterruptSpinLock(PortData->InterruptObject, OldIrql);
147 KeReleaseSpinLock(&ChanExt->PdoListLock, OldLevel);
148
149 return Result;
150}
Entry
Definition: section.c:5210
SINGLE_LIST_ENTRY PdoList
Definition: atapi.h:446
volatile LONG EventsPending
Definition: atapi.h:300
Definition: ntbasedef.h:640
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:641
UCHAR PathId
Definition: atapi.h:65
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409

Referenced by AtaPortConfigureDevice(), AtaPortDeviceChangePower(), AtaPortEnumerateDevice(), and AtaPortRecoveryFromError().

◆ AtaPortGetNextEvent()

static BOOLEAN AtaPortGetNextEvent ( _In_ PATAPORT_PORT_DATA  PortData,
_Out_ ATA_PORT_ACTION Action 
)
static

Definition at line 458 of file portstate.c.

461{
463 ULONG i, EventIndex;
465
466 OldIrql = KeAcquireInterruptSpinLock(PortData->InterruptObject);
467
468 /* Handle events by priority order */
469 Success = _BitScanForward(&EventIndex, PortData->Worker.EventsPending);
470 if (!Success)
471 {
473
474 /* Resume port I/O */
475 ASSERT(!(PortData->InterruptFlags & PORT_INT_FLAG_IS_IO_ACTIVE));
476 _InterlockedOr(&PortData->InterruptFlags, PORT_INT_FLAG_IS_IO_ACTIVE);
477
478 /* Complete failed request */
479 Request = PortData->Worker.FailedRequest;
480 if (Request && !(PortData->Worker.PausedSlotsBitmap & (1 << Request->Slot)))
481 {
483 }
484 PortData->Worker.FailedRequest = NULL;
485
486 /* Requeue saved commands */
487 for (i = 0; i < MAX_SLOTS; ++i)
488 {
489 if (!(PortData->Worker.PausedSlotsBitmap & (1 << i)))
490 continue;
491
492 Request = PortData->Slots[i];
494 ASSERT(Request != &PortData->Worker.InternalRequest);
495
496 Request->SrbStatus = SRB_STATUS_BUSY;
497 Request->InternalState = REQUEST_STATE_REQUEUE;
499 }
500
501 PortData->Worker.PausedSlotsBitmap = 0;
502 }
503
504 KeReleaseInterruptSpinLock(PortData->InterruptObject, OldIrql);
505
506 *Action = 1 << EventIndex;
507 return Success;
508}
unsigned char BOOLEAN
Definition: actypes.h:127
#define REQUEST_STATE_REQUEUE
Definition: ata_shared.h:270
#define ASSERT_REQUEST(Request)
Definition: atapi.h:326
#define PORT_INT_FLAG_IS_IO_ACTIVE
Definition: atapi.h:360
#define MAX_SLOTS
Definition: atapi.h:207
VOID AtaReqStartCompletionDpc(_In_ PATA_DEVICE_REQUEST Request)
Definition: scsi.c:777
#define SRB_STATUS_BUSY
Definition: srb.h:345
@ Success
Definition: eventcreate.c:712
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
unsigned char _BitScanForward(unsigned long *_Index, unsigned long _Mask)
Definition: intrin_arm.h:57

Referenced by AtaPortRunStateMachine().

◆ AtaPortMarkDeviceFailed()

static VOID AtaPortMarkDeviceFailed ( _In_ PATAPORT_PORT_DATA  PortData,
_In_ PATAPORT_DEVICE_EXTENSION  DevExt 
)
static

Definition at line 236 of file portstate.c.

239{
240 /* Ignore bad or incompatible devices, so we do not access them at all */
241 if (++DevExt->Worker.ResetRetryCount >= 4)
242 {
243 ERR("CH %lu: Too many reset attempts for the device %u, giving up\n",
244 PortData->PortNumber,
245 DevExt->Device.AtaScsiAddress.TargetId);
246
247 DevExt->Worker.Flags |= DEV_WORKER_FLAG_REMOVED;
248
249 PortData->Worker.BadDeviceBitmap |= 1 << (ULONG)DevExt->Device.AtaScsiAddress.TargetId;
250 }
251}
#define ERR(fmt,...)
Definition: precomp.h:57

Referenced by AtaPortConfigureDevice(), AtaPortDeviceChangePower(), AtaPortEnumerateDevice(), and AtaPortRecoveryFromError().

◆ AtaPortNotification()

VOID __cdecl AtaPortNotification ( _In_ PORT_NOTIFICATION_TYPE  NotificationType,
_In_ PVOID  PortContext,
  ... 
)

Definition at line 755 of file portstate.c.

759{
761 va_list ap;
762
764
765 TRACE("CH %lu: Notification %lu\n", PortData->PortNumber, NotificationType);
766
767 switch (NotificationType)
768 {
770 {
772 break;
773 }
774
775 case AtaResetDetected:
776 {
777 ASSERT(PortData->Worker.Thread == KeGetCurrentThread());
780 break;
781 }
782
784 {
786
789 else
790 TRACE("CH %lu: Ignore link IRQ\n", PortData->PortNumber);
791 break;
792 }
793
794 case AtaRequestFailed:
795 {
796 AtaPortQueueEvent(PortData,
797 NULL,
800 break;
801 }
802
804 {
806 break;
807 }
808
809 default:
810 ERR("CH %lu: Unsupported notification %lu\n", PortData->PortNumber, NotificationType);
811 break;
812 }
813
814 va_end(ap);
815}
_In_ PVOID PortContext
Definition: ata_shared.h:375
@ AtaRequestFailed
Definition: ata_shared.h:77
@ AtaBusChangeDetected
Definition: ata_shared.h:76
@ AtaAsyncNotificationDetected
Definition: ata_shared.h:78
@ AtaResetDetected
Definition: ata_shared.h:75
@ AtaRequestComplete
Definition: ata_shared.h:74
@ ACTION_DEVICE_ERROR
Definition: atapi.h:249
@ ACTION_PORT_RESET
Definition: atapi.h:243
#define va_end(v)
Definition: stdarg.h:28
#define va_arg(v, l)
Definition: stdarg.h:27
#define va_start(v, l)
Definition: stdarg.h:26
char * va_list
Definition: vadefs.h:50
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define KeGetCurrentThread
Definition: hal.h:55
static VOID AtaPortOnResetNotification(_In_ PATAPORT_PORT_DATA PortData, _In_ ULONG DeviceBitmap)
Definition: portstate.c:165
static VOID AtaPortOnAsyncNotification(_In_ PATAPORT_PORT_DATA PortData, _In_ ULONG DeviceBitmap)
Definition: portstate.c:154
static VOID AtaPortOnRequestComplete(_In_ PATAPORT_PORT_DATA PortData, _In_ ULONG CommandsCompleted)
Definition: portstate.c:208
volatile LONG InterruptFlags
Definition: atapi.h:359
ULONG PortNumber
Definition: atapi.h:396
ATA_WORKER_CONTEXT Worker
Definition: atapi.h:400
PKTHREAD Thread
Definition: atapi.h:295
_In_ WDF_SPECIAL_FILE_TYPE NotificationType
Definition: wdfdevice.h:1024
void int int ULONGLONG int va_list * ap
Definition: winesup.h:36

◆ AtaPortOnAsyncNotification()

static VOID AtaPortOnAsyncNotification ( _In_ PATAPORT_PORT_DATA  PortData,
_In_ ULONG  DeviceBitmap 
)
static

Definition at line 154 of file portstate.c.

157{
159
160 KeInsertQueueDpc(&PortData->Worker.NotificationDpc, UlongToPtr(DeviceBitmap), NULL);
161}
BOOLEAN NTAPI KeInsertQueueDpc(IN PKDPC Dpc, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: dpc.c:725
#define UlongToPtr(u)
Definition: config.h:106

Referenced by AtaPortNotification().

◆ AtaPortOnRequestComplete()

static VOID AtaPortOnRequestComplete ( _In_ PATAPORT_PORT_DATA  PortData,
_In_ ULONG  CommandsCompleted 
)
static

Definition at line 208 of file portstate.c.

211{
212 ULONG Slot;
213
215
216 PortData->ActiveSlotsBitmap &= ~CommandsCompleted;
217
218 while (_BitScanForward(&Slot, CommandsCompleted) != 0)
219 {
221
222 CommandsCompleted &= ~(1 << Slot);
223
224 Request = PortData->Slots[Slot];
226 ASSERT(Request->Slot == Slot);
227
229 }
230
232}
SLIST_HEADER AtapCompletionQueueList
Definition: scsi.c:14
KDPC AtapCompletionDpc
Definition: scsi.c:15
#define InterlockedPushEntrySList(SListHead, SListEntry)
Definition: rtlfuncs.h:3406

Referenced by AtaPortNotification().

◆ AtaPortOnResetNotification()

static VOID AtaPortOnResetNotification ( _In_ PATAPORT_PORT_DATA  PortData,
_In_ ULONG  DeviceBitmap 
)
static

Definition at line 165 of file portstate.c.

168{
170 ATA_SCSI_ADDRESS AtaScsiAddress;
172
173 /*
174 * We are about to reset the channel which will in turn
175 * cause the affected devices to lose their software settings.
176 * Enqueue a config event so the state machine can re-initialize all devices later on.
177 */
178 _InterlockedOr(&PortData->Worker.EventsPending,
182
183 ChanExt = CONTAINING_RECORD(PortData, ATAPORT_CHANNEL_EXTENSION, PortData);
184
185 AtaScsiAddress.AsULONG = 0;
186 while (TRUE)
187 {
189
190 DevExt = AtaFdoFindNextDeviceByPath(ChanExt, &AtaScsiAddress, FALSE, NULL);
191 if (!DevExt)
192 break;
193
194 if (!(DeviceBitmap & (1 << (ULONG)AtaScsiAddress.TargetId)))
195 continue;
196
199 else
200 Event = ACTION_ENUM_DEVICE; // ACPI _GTF is not ready yet
201
203 }
204}
@ ACTION_PORT_TIMING
Definition: atapi.h:247
@ ACTION_ENUM_DEVICE
Definition: atapi.h:246
enum _ATA_PORT_ACTION ATA_PORT_ACTION
#define DEVICE_PNP_STARTED
Definition: atapi.h:92

Referenced by AtaPortNotification(), and AtaPortResetPort().

◆ AtaPortQueueEvent()

static VOID AtaPortQueueEvent ( _In_ PATAPORT_PORT_DATA  PortData,
_In_opt_ PATAPORT_DEVICE_EXTENSION  DevExt,
_In_opt_ PATA_DEVICE_REQUEST  FailedRequest,
_In_ ATA_PORT_ACTION  Action 
)
static

Definition at line 16 of file portstate.c.

21{
23
25 {
27 {
28 if (FailedRequest)
29 {
30 ASSERT_REQUEST(FailedRequest);
31
32 DevExt = CONTAINING_RECORD(FailedRequest->Device, ATAPORT_DEVICE_EXTENSION, Device);
33
34 if (FailedRequest->Flags & REQUEST_FLAG_INTERNAL)
35 {
36 Action &= ~ACTION_DEVICE_ERROR;
37 }
38 else
39 {
40 ASSERT(PortData->Worker.FailedRequest == NULL);
41 PortData->Worker.FailedRequest = FailedRequest;
42 }
43 }
44 else
45 {
46 Action &= ~ACTION_DEVICE_ERROR;
48 }
49 }
50
51 /* Special case for the internal request */
52 if ((PortData->ActiveSlotsBitmap & 1) &&
53 (PortData->Slots[0]->Flags & REQUEST_FLAG_INTERNAL))
54 {
55 PATA_DEVICE_REQUEST InternalRequest = &PortData->Worker.InternalRequest;
56
58 InternalRequest->SrbStatus = SRB_STATUS_BUS_RESET;
59
60 PortData->ActiveSlotsBitmap &= ~1;
61
62 /* Internal request failed, kick off the port thread */
63 AtaReqStartCompletionDpc(InternalRequest);
64 }
65
66 /* Error recovery, save any commands pending on this port */
67 PortData->Worker.PausedSlotsBitmap |= PortData->ActiveSlotsBitmap;
68 PortData->ActiveSlotsBitmap = 0;
69
70 PortData->AbortChannel(PortData->ChannelContext, !!(Action & ACTION_PORT_RESET));
71 }
72
73 if (DevExt)
74 _InterlockedOr(&DevExt->Worker.EventsPending, Action);
75 _InterlockedOr(&PortData->Worker.EventsPending, Action);
76
77 /* Kick off the port thread */
78 if (PortData->InterruptFlags & PORT_INT_FLAG_IS_IO_ACTIVE)
79 {
80 _InterlockedAnd(&PortData->InterruptFlags, ~PORT_INT_FLAG_IS_IO_ACTIVE);
81 KeInsertQueueDpc(&PortData->Worker.Dpc, NULL, NULL);
82 }
83}
#define SRB_STATUS_BUS_RESET
Definition: srb.h:353

Referenced by AtaDeviceQueueEvent(), AtaPortNotification(), and AtaPortTimeout().

◆ AtaPortRecoveryFromError()

static NTSTATUS AtaPortRecoveryFromError ( _In_ PATAPORT_PORT_DATA  PortData)
static

Definition at line 376 of file portstate.c.

378{
381
383 if (!DevExt)
384 return STATUS_SUCCESS;
385
386 Status = AtaPortDeviceProcessError(PortData, DevExt);
388 {
389 AtaPortMarkDeviceFailed(PortData, DevExt);
390 return Status;
391 }
392
394 return STATUS_SUCCESS;
395}
NTSTATUS AtaPortDeviceProcessError(_In_ PATAPORT_PORT_DATA PortData, _In_ PATAPORT_DEVICE_EXTENSION DevExt)
Definition: dev_error.c:642

Referenced by AtaPortRunStateMachine().

◆ AtaPortResetPort()

static NTSTATUS AtaPortResetPort ( _In_ PATAPORT_PORT_DATA  PortData)
static

Definition at line 294 of file portstate.c.

296{
297 _InterlockedOr(&PortData->InterruptFlags, PORT_INT_FLAG_IGNORE_LINK_IRQ);
298 PortData->ResetChannel(PortData->ChannelContext);
299 _InterlockedAnd(&PortData->InterruptFlags, ~PORT_INT_FLAG_IGNORE_LINK_IRQ);
300
301 AtaPortEnumeratePort(PortData);
303
304 AtaPortClearPortAction(&PortData->Worker, ACTION_PORT_RESET);
305
306 /*
307 * Reset bus timings, as attached devices
308 * may reset their current transfer mode to default during the processing of a software reset
309 * and the subsequent IDENTIFY DEVICE command would end up using incorrect timings.
310 */
311 AtaPortSelectTimings(PortData, TRUE);
312
313 if (++PortData->Worker.ResetRetryCount >= 10)
314 {
315 ERR("CH %lu: Too many port reset attempts, giving up\n", PortData->PortNumber);
316 PortData->Worker.BadDeviceBitmap = MAXULONG;
317 }
318
319 return STATUS_SUCCESS;
320}
VOID AtaPortSelectTimings(_In_ PATAPORT_PORT_DATA PortData, _In_ BOOLEAN ForceCompatibleTimings)
Definition: dev_timings.c:258
static NTSTATUS AtaPortEnumeratePort(_In_ PATAPORT_PORT_DATA PortData)
Definition: portstate.c:255
#define MAXULONG
Definition: typedefs.h:251

Referenced by AtaPortRunStateMachine().

◆ AtaPortRunStateMachine()

static VOID AtaPortRunStateMachine ( _In_ PATAPORT_PORT_DATA  PortData)
static

Definition at line 512 of file portstate.c.

514{
517
518 while (TRUE)
519 {
520 if (!AtaPortGetNextEvent(PortData, &Action))
521 break;
522
523#if DBG
524 if (PortData->Worker.StateLoopCount++ > 1500)
525 {
526 ERR("CH %lu: Loop detected %lx\n", PortData->PortNumber,
527 PortData->Worker.EventsPending);
528 ASSERT(FALSE);
529 }
530#endif
531
532 switch (Action)
533 {
535 Status = AtaPortResetPort(PortData);
536 break;
537 case ACTION_ENUM_PORT:
538 Status = AtaPortEnumeratePort(PortData);
539 break;
543 break;
545 Status = AtaPortSetTransferMode(PortData);
546 break;
548 Status = AtaPortConfigureDevice(PortData);
549 break;
552 break;
555 break;
556
557 default:
558 ASSERT(FALSE);
560 }
561
563 _InterlockedOr(&PortData->Worker.EventsPending, ACTION_PORT_RESET);
564 }
565}
#define UNREACHABLE
static NTSTATUS AtaPortDeviceChangePower(_In_ PATAPORT_PORT_DATA PortData)
Definition: portstate.c:424
static NTSTATUS AtaPortEnumerateDevice(_In_ PATAPORT_PORT_DATA PortData, _In_ ATA_PORT_ACTION Action)
Definition: portstate.c:324
static NTSTATUS AtaPortConfigureDevice(_In_ PATAPORT_PORT_DATA PortData)
Definition: portstate.c:399
static BOOLEAN AtaPortGetNextEvent(_In_ PATAPORT_PORT_DATA PortData, _Out_ ATA_PORT_ACTION *Action)
Definition: portstate.c:458
static NTSTATUS AtaPortResetPort(_In_ PATAPORT_PORT_DATA PortData)
Definition: portstate.c:294
static NTSTATUS AtaPortRecoveryFromError(_In_ PATAPORT_PORT_DATA PortData)
Definition: portstate.c:376
static NTSTATUS AtaPortSetTransferMode(_In_ PATAPORT_PORT_DATA PortData)
Definition: portstate.c:447

Referenced by AtaPortWorkerThread().

◆ AtaPortSendRequest()

NTSTATUS AtaPortSendRequest ( _In_ PATAPORT_PORT_DATA  PortData,
_In_ PATAPORT_DEVICE_EXTENSION  DevExt 
)

Definition at line 831 of file portstate.c.

834{
835 PATA_DEVICE_REQUEST Request = &PortData->Worker.InternalRequest;
837
839 {
840 INFO("CH %lu: Send CDB %u %02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
841 PortData->PortNumber,
842 DevExt->Device.AtaScsiAddress.TargetId,
843 Request->Cdb[0],
844 Request->Cdb[1],
845 Request->Cdb[2],
846 Request->Cdb[3],
847 Request->Cdb[4],
848 Request->Cdb[5],
849 Request->Cdb[6]);
850 }
851 else
852 {
853 INFO("CH %lu: Send TF %u %02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
854 PortData->PortNumber,
855 DevExt->Device.AtaScsiAddress.TargetId,
856 Request->TaskFile.Command,
857 Request->TaskFile.Feature,
858 Request->TaskFile.SectorCount,
859 Request->TaskFile.LowLba,
860 Request->TaskFile.MidLba,
861 Request->TaskFile.HighLba,
862 Request->TaskFile.DriveSelect);
863 }
864
865 KeClearEvent(&PortData->Worker.CompletionEvent);
866
868 Request->Device = (PATA_IO_CONTEXT_COMMON)&DevExt->Device;
869
870 PortData->Worker.OldRequest = PortData->Slots[0];
871 PortData->Slots[0] = Request;
872
874
875 KeAcquireSpinLockAtDpcLevel(&PortData->QueueLock);
876 PortData->ActiveTimersBitmap |= 1 << 0;
877 KeReleaseSpinLockFromDpcLevel(&PortData->QueueLock);
878
880
882
883 KeWaitForSingleObject(&PortData->Worker.CompletionEvent, Executive, KernelMode, FALSE, NULL);
884
885 /* Stop the timer */
886 KeAcquireSpinLock(&PortData->QueueLock, &OldIrql);
887 PortData->ActiveTimersBitmap = 0;
888 KeReleaseSpinLock(&PortData->QueueLock, OldIrql);
889
890 PortData->Slots[0] = PortData->Worker.OldRequest;
891
892 if ((Request->SrbStatus == SRB_STATUS_TIMEOUT) ||
893 (Request->SrbStatus == SRB_STATUS_BUS_RESET))
894 {
896 }
897
898 if (Request->SrbStatus == SRB_STATUS_SUCCESS)
899 return STATUS_SUCCESS;
900
902}
struct _ATA_IO_CONTEXT_COMMON * PATA_IO_CONTEXT_COMMON
VOID AtaReqSendRequest(_In_ PATA_DEVICE_REQUEST Request)
Definition: scsi.c:632
#define SRB_STATUS_TIMEOUT
Definition: srb.h:349
#define SRB_STATUS_SUCCESS
Definition: srb.h:341
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
#define REQUEST_FLAG_PACKET_COMMAND
Definition: hwidep.h:169
#define KernelMode
Definition: asm.h:38
#define KeAcquireSpinLockAtDpcLevel(SpinLock)
Definition: ke.h:125
#define KeReleaseSpinLockFromDpcLevel(SpinLock)
Definition: ke.h:135
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
@ Executive
Definition: ketypes.h:467

Referenced by AtaDeviceEnableMsnFeature(), AtaDeviceExecuteAcpiTaskFile(), AtaDeviceFlushCache(), AtaDeviceLockDeviceParameters(), AtaDeviceLockSecurityModeFeatureCommands(), AtaDeviceSendIdentify(), AtaDeviceSendInquiry(), AtaDeviceSendReadNcqCommandErrorLog(), AtaDeviceSendRequestSense(), AtaDeviceSendRequestSenseExt(), AtaDeviceSetDmaTransferMode(), AtaDeviceSetGeometry(), AtaDeviceSetIdleMode(), AtaDeviceSetMultipleMode(), AtaDeviceSetPioTransferMode(), AtaDeviceSetStandbyMode(), and AtaDeviceSpinUp().

◆ AtaPortSetTransferMode()

static NTSTATUS AtaPortSetTransferMode ( _In_ PATAPORT_PORT_DATA  PortData)
static

Definition at line 447 of file portstate.c.

449{
450 AtaPortSelectTimings(PortData, FALSE);
451 AtaPortClearPortAction(&PortData->Worker, ACTION_PORT_TIMING);
452
453 return STATUS_SUCCESS;
454}

Referenced by AtaPortRunStateMachine().

◆ AtaPortSignalWorkerThread()

DECLSPEC_NOINLINE_FROM_PAGED VOID AtaPortSignalWorkerThread ( _In_ PATAPORT_PORT_DATA  PortData)

Definition at line 963 of file portstate.c.

965{
967
968 KeAcquireSpinLock(&PortData->Worker.Lock, &OldIrql);
969 KeSetEvent(&PortData->Worker.ThreadEvent, IO_NO_INCREMENT, FALSE);
970 KeReleaseSpinLock(&PortData->Worker.Lock, OldIrql);
971}

Referenced by AtaFdoDestroyPortThread(), and AtaPortWorkerSignalDpc().

◆ AtaPortTimeout()

VOID AtaPortTimeout ( _In_ PATAPORT_PORT_DATA  PortData,
_In_ ULONG  Slot 
)

Definition at line 905 of file portstate.c.

908{
911
913
914 Request = PortData->Slots[Slot];
916
918
919 ERR("CH %lu: Slot %lu (%08lx) timed out %lx (%lus) %u '%s'\n",
920 PortData->PortNumber,
921 Slot,
922 1 << Slot,
923 Request->Flags,
924 Request->TimeOut,
926 DevExt->FriendlyName);
928 {
929 ERR("CH %lu: CDB %02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
930 PortData->PortNumber,
931 Request->Cdb[0],
932 Request->Cdb[1],
933 Request->Cdb[2],
934 Request->Cdb[3],
935 Request->Cdb[4],
936 Request->Cdb[5],
937 Request->Cdb[6]);
938 }
939 else
940 {
941 ERR("CH %lu: TF %02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
942 PortData->PortNumber,
943 Request->TaskFile.Command,
944 Request->TaskFile.Feature,
945 Request->TaskFile.SectorCount,
946 Request->TaskFile.LowLba,
947 Request->TaskFile.MidLba,
948 Request->TaskFile.HighLba,
949 Request->TaskFile.DriveSelect);
950 }
951
952 Request->SrbStatus = SRB_STATUS_TIMEOUT;
953
954 /* The active command has timed out, set the ATA outputs to something meaningful */
955 Request->Output.Status = IDE_STATUS_ERROR;
956 Request->Output.Error = IDE_ERROR_COMMAND_ABORTED;
957
959}
#define IDE_STATUS_ERROR
Definition: atapi.h:125
#define IDE_ERROR_COMMAND_ABORTED
Definition: atapi.h:158

Referenced by AtaPortIoTimer().

◆ AtaPortWaitForIdle()

static VOID AtaPortWaitForIdle ( _In_ PATAPORT_PORT_DATA  PortData)
static

Definition at line 569 of file portstate.c.

571{
573 BOOLEAN DoWait = FALSE;
574
575 KeAcquireSpinLock(&PortData->QueueLock, &OldIrql);
576 KeClearEvent(&PortData->QueueStoppedEvent);
577 if (!AtaPortQueueEmpty(PortData))
578 {
579 PortData->QueueFlags |= PORT_QUEUE_FLAG_SIGNAL_STOP;
580 DoWait = TRUE;
581 }
582 KeReleaseSpinLock(&PortData->QueueLock, OldIrql);
583 if (DoWait)
584 {
585 KeWaitForSingleObject(&PortData->QueueStoppedEvent, Executive, KernelMode, FALSE, NULL);
586 }
587}
#define PORT_QUEUE_FLAG_SIGNAL_STOP
Definition: atapi.h:370
FORCEINLINE BOOLEAN AtaPortQueueEmpty(_In_ PATAPORT_PORT_DATA PortData)
Definition: atapi.h:573

Referenced by AtaPortEnterStateMachine().

◆ AtaPortWorkerClearSignal()

static VOID AtaPortWorkerClearSignal ( _In_ PATAPORT_PORT_DATA  PortData)
static

Definition at line 717 of file portstate.c.

719{
721
722 KeAcquireSpinLock(&PortData->Worker.Lock, &OldIrql);
723 KeClearEvent(&PortData->Worker.ThreadEvent);
724 KeReleaseSpinLock(&PortData->Worker.Lock, OldIrql);
725}

Referenced by AtaPortWorkerThread().

◆ AtaPortWorkerSignalDpc()

VOID NTAPI AtaPortWorkerSignalDpc ( _In_ PKDPC  Dpc,
_In_opt_ PVOID  DeferredContext,
_In_opt_ PVOID  SystemArgument1,
_In_opt_ PVOID  SystemArgument2 
)

Definition at line 975 of file portstate.c.

980{
982
986
988}
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
DECLSPEC_NOINLINE_FROM_PAGED VOID AtaPortSignalWorkerThread(_In_ PATAPORT_PORT_DATA PortData)
Definition: portstate.c:963
_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:740
_In_opt_ PVOID DeferredContext
Definition: ketypes.h:739
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:741

◆ AtaPortWorkerThread()

VOID NTAPI AtaPortWorkerThread ( _In_ PVOID  StartContext)

Definition at line 729 of file portstate.c.

731{
732 PATAPORT_PORT_DATA PortData = StartContext;
733
734 while (TRUE)
735 {
737 Executive,
739 FALSE,
740 NULL);
741 if (PortData->PortFlags & PORT_FLAG_EXIT_THREAD)
742 break;
743
744 AtaPortWorkerClearSignal(PortData);
745 AtaPortEnterStateMachine(PortData);
746 AtaPortRunStateMachine(PortData);
747 AtaPortExitStateMachine(PortData);
748 }
749
751}
#define PORT_FLAG_EXIT_THREAD
Definition: atapi.h:346
NTSTATUS NTAPI PsTerminateSystemThread(IN NTSTATUS ExitStatus)
Definition: kill.c:1153
static VOID AtaPortExitStateMachine(_In_ PATAPORT_PORT_DATA PortData)
Definition: portstate.c:654
static VOID AtaPortWorkerClearSignal(_In_ PATAPORT_PORT_DATA PortData)
Definition: portstate.c:717
static VOID AtaPortRunStateMachine(_In_ PATAPORT_PORT_DATA PortData)
Definition: portstate.c:512
static VOID AtaPortEnterStateMachine(_In_ PATAPORT_PORT_DATA PortData)
Definition: portstate.c:591
ULONG PortFlags
Definition: atapi.h:335
KEVENT ThreadEvent
Definition: atapi.h:274