ReactOS 0.4.16-dev-2633-g8dc9e50
fdo.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS ATA Port Driver
3 * LICENSE: MIT (https://spdx.org/licenses/MIT)
4 * PURPOSE: ATA channel device object (FDO) dispatch routines
5 * COPYRIGHT: Copyright 2026 Dmitry Borisov <di.sean@protonmail.com>
6 */
7
8/* INCLUDES *******************************************************************/
9
10#include "atapi.h"
11
12/* GLOBALS ********************************************************************/
13
14DECLARE_PAGED_WSTRING(AtapDevSymLinkFormat, L"\\Device\\ScsiPort%lu");
15DECLARE_PAGED_WSTRING(AtapDosSymLinkFormat, L"\\DosDevices\\Scsi%lu:");
16
17/* FUNCTIONS ******************************************************************/
18
19static
20CODE_SEG("PAGE")
24{
25 UNICODE_STRING ChannelName;
26 ULONG ScsiAdapter, ScsiPortCount;
27 WCHAR ChannelNameBuffer[sizeof("\\Device\\Ide\\IdePort99999")];
29 DECLARE_PAGED_WSTRING(FdoFormat, L"\\Device\\Ide\\IdePort%lu");
30
31 PAGED_CODE();
32
33 if (ChanExt->PortData.PortFlags & PORT_FLAG_SYMLINK_CREATED)
34 return STATUS_SUCCESS;
35
36 Status = RtlStringCbPrintfW(ChannelNameBuffer,
37 sizeof(ChannelNameBuffer),
38 FdoFormat,
39 ChanExt->DeviceObjectNumber);
41 RtlInitUnicodeString(&ChannelName, ChannelNameBuffer);
42
44
45 /* Search for a free SCSI port adapter in the system */
46 for (ScsiAdapter = 0; ScsiAdapter <= ScsiPortCount; ++ScsiAdapter)
47 {
48 WCHAR SymLinkNameBuffer[sizeof("\\DosDevices\\Scsi99999:")];
49 UNICODE_STRING SymLinkName;
50
51 Status = RtlStringCbPrintfW(SymLinkNameBuffer,
52 sizeof(SymLinkNameBuffer),
53 AtapDevSymLinkFormat,
56 RtlInitUnicodeString(&SymLinkName, SymLinkNameBuffer);
57
58 /* Create a symbolic link '\Device\ScsiPortX' -> '\Device\Ide\IdePortN' */
59 Status = IoCreateSymbolicLink(&SymLinkName, &ChannelName);
60 if (!NT_SUCCESS(Status))
61 continue;
62
63 INFO("Symlink created '%wZ' -> '%wZ'\n", &SymLinkName, &ChannelName);
64
65 Status = RtlStringCbPrintfW(SymLinkNameBuffer,
66 sizeof(SymLinkNameBuffer),
67 AtapDosSymLinkFormat,
70 RtlInitUnicodeString(&SymLinkName, SymLinkNameBuffer);
71
72 /* Create a symbolic link '\DosDevices\ScsiX:' -> '\Device\Ide\IdePortN' */
73 Status = IoCreateSymbolicLink(&SymLinkName, &ChannelName);
74 if (NT_SUCCESS(Status))
75 {
76 INFO("Symlink created '%wZ' -> '%wZ'\n", &SymLinkName, &ChannelName);
77 }
78
79 /* Register ourselves (ATA channel) as a SCSI port adapter */
81
82 ChanExt->ScsiPortNumber = ScsiAdapter;
83 ChanExt->PortData.PortFlags |= PORT_FLAG_SYMLINK_CREATED;
84 break;
85 }
86
87 return Status;
88}
89
90static
91CODE_SEG("PAGE")
94 _In_ PATAPORT_PORT_DATA PortData)
95{
100
101 PAGED_CODE();
102
103 if (PortData->LocalBuffer)
104 return STATUS_SUCCESS;
105
107 HighestAcceptableAddress.QuadPart = 0xFFFFFFFF; // 32-bit DMA
108 BoundaryAddressMultiple.QuadPart = 0x10000; // 64k, for PATA compability
114 if (!PortData->LocalBuffer)
116
117 PhysicalAddress = MmGetPhysicalAddress(PortData->LocalBuffer);
118
119 PortData->LocalSgList.NumberOfElements = 1;
120 PortData->LocalSgList.Elements[0].Length = ATA_LOCAL_BUFFER_SIZE;
121 PortData->LocalSgList.Elements[0].Address.QuadPart = PhysicalAddress.QuadPart;
122
123 return STATUS_SUCCESS;
124}
125
126static
127CODE_SEG("PAGE")
130 _In_ PATAPORT_PORT_DATA PortData)
131{
133 HANDLE ThreadHandle;
135
136 PAGED_CODE();
137
138 if (PortData->Worker.Thread)
139 return STATUS_SUCCESS;
140
141 KeInitializeEvent(&PortData->Worker.ThreadEvent, NotificationEvent, FALSE);
142
143 Status = PsCreateSystemThread(&ThreadHandle,
146 NULL,
147 NULL,
149 PortData);
150 if (!NT_SUCCESS(Status))
151 return Status;
152
153 Status = ObReferenceObjectByHandle(ThreadHandle,
155 NULL,
157 (PVOID*)&PortData->Worker.Thread,
158 NULL);
159 if (!NT_SUCCESS(Status))
160 return Status;
161
162 ZwClose(ThreadHandle);
163
164 return STATUS_SUCCESS;
165}
166
167static
168CODE_SEG("PAGE")
169VOID
172{
173 PATAPORT_PORT_DATA PortData = &ChanExt->PortData;
174
175 PAGED_CODE();
176
177 if (!PortData->Worker.Thread)
178 return;
179
180 PortData->PortFlags |= PORT_FLAG_EXIT_THREAD;
182
184
186
187 PortData->Worker.Thread = NULL;
188}
189
190static
191CODE_SEG("PAGE")
192VOID
195{
197 UNICODE_STRING SymLinkName;
198 WCHAR SymLinkNameBuffer[sizeof("\\DosDevices\\Scsi99999:")];
199
200 PAGED_CODE();
201
202 if (!(ChanExt->PortData.PortFlags & PORT_FLAG_SYMLINK_CREATED))
203 return;
204
205 /* Delete the '\DosDevices\\ScsiX:' symbolic link */
206 Status = RtlStringCbPrintfW(SymLinkNameBuffer,
207 sizeof(SymLinkNameBuffer),
208 AtapDevSymLinkFormat,
209 ChanExt->ScsiPortNumber);
211 RtlInitUnicodeString(&SymLinkName, SymLinkNameBuffer);
212 (VOID)IoDeleteSymbolicLink(&SymLinkName);
213
214 /* Delete the '\Device\\ScsiPortX' symbolic link */
215 Status = RtlStringCbPrintfW(SymLinkNameBuffer,
216 sizeof(SymLinkNameBuffer),
217 AtapDosSymLinkFormat,
218 ChanExt->ScsiPortNumber);
220 RtlInitUnicodeString(&SymLinkName, SymLinkNameBuffer);
221 (VOID)IoDeleteSymbolicLink(&SymLinkName);
222
223 /* Unregister the SCSI port adapter */
225}
226
227CODE_SEG("PAGE")
232{
233 PATAPORT_PORT_DATA PortData = &ChanExt->PortData;
234 PCIIDEX_CHANNEL_INTERFACE ChannelInterface = { 0 };
236
237 PAGED_CODE();
238
239 INFO("Starting channel %lu\n", ChanExt->DeviceObjectNumber);
240
241 /* Get the interface of ATA channel */
242 Status = AtaPnpQueryInterface(&ChanExt->Common,
243 &GUID_PCIIDE_INTERFACE_ROS,
244 &ChannelInterface,
246 sizeof(ChannelInterface));
247 if (!NT_SUCCESS(Status))
248 {
249 ERR("Failed to query channel interface %lx\n", Status);
250 return Status;
251 }
252 PortData->ChannelContext = ChannelInterface.ChannelContext;
253 PortData->AttachChannel = ChannelInterface.AttachChannel;
254 PortData->SetDeviceData = ChannelInterface.SetDeviceData;
255 PortData->GetInitTaskFile = ChannelInterface.GetInitTaskFile;
256 PortData->DowngradeInterfaceSpeed = ChannelInterface.DowngradeInterfaceSpeed;
257 PortData->InterruptObject = ChannelInterface.InterruptObject;
258 PortData->AbortChannel = ChannelInterface.AbortChannel;
259 PortData->ResetChannel = ChannelInterface.ResetChannel;
260 PortData->EnumerateChannel = ChannelInterface.EnumerateChannel;
261 PortData->IdentifyDevice = ChannelInterface.IdentifyDevice;
262 PortData->SetTransferMode = ChannelInterface.SetTransferMode;
263 PortData->AllocateSlot = ChannelInterface.AllocateSlot;
264 PortData->PreparePrdTable = ChannelInterface.PreparePrdTable;
265 PortData->PrepareIo = ChannelInterface.PrepareIo;
266 PortData->StartIo = ChannelInterface.StartIo;
267 PortData->MaxTargetId = ChannelInterface.MaxTargetId;
268 PortData->MaximumTransferLength = ChannelInterface.MaximumTransferLength;
269 PortData->MaximumPhysicalPages = ChannelInterface.MaximumPhysicalPages;
270 PortData->QueueDepth = ChannelInterface.QueueDepth;
271 PortData->PortNumber = ChannelInterface.Channel;
272 PortData->DmaAdapter = ChannelInterface.DmaAdapter;
273 PortData->ChannelObject = ChannelInterface.ChannelObject;
274
276 PortData->FreeSlotsBitmap =
277 PortData->MaxSlotsBitmap = NUM_TO_BITMAP(PortData->QueueDepth);
278 /* We need the slot numbers to start from zero */
279 PortData->LastUsedSlot = RTL_BITS_OF(ULONG) - 1;
280
281 if (!(ChannelInterface.TransferModeSupported & ~PIO_ALL))
282 PortData->PortFlags |= PORT_FLAG_PIO_ONLY;
283
284 if (ChannelInterface.Flags & ATA_CHANNEL_FLAG_PIO_VIA_DMA)
285 PortData->PortFlags |= PORT_FLAG_PIO_VIA_DMA;
286
287 if (ChannelInterface.Flags & ATA_CHANNEL_FLAG_NCQ)
288 PortData->PortFlags |= PORT_FLAG_NCQ;
289
290 if (ChannelInterface.Flags & ATA_CHANNEL_FLAG_IS_AHCI)
291 PortData->PortFlags |= PORT_FLAG_IS_AHCI;
292
293 if (ChannelInterface.Flags & ATA_CHANNEL_FLAG_IS_EXTERNAL)
294 PortData->PortFlags |= PORT_FLAG_IS_EXTERNAL;
295
296 if (ChannelInterface.Flags & ATA_CHANNEL_FLAG_PIO_FOR_LBA48_XFER)
298
299 if (ChannelInterface.HwSyncObject)
300 {
301 PortData->PortFlags |= PORT_FLAG_IS_SIMPLEX;
302 PortData->HwSyncObject = ChannelInterface.HwSyncObject;
303 }
304
305 /* Reserve PIO memory resources early. Storage drivers should not fail paging I/O operations */
306 if (!(ChannelInterface.Flags & ATA_CHANNEL_FLAG_PIO_VIA_DMA) && !PortData->ReservedVaSpace)
307 {
308 PortData->ReservedVaSpace = MmAllocateMappingAddress(ATA_RESERVED_PAGES * PAGE_SIZE,
310 }
311
313 if (!NT_SUCCESS(Status))
314 {
315 ERR("CH %lu: Failed to allocate local buffer 0x%lx\n", PortData->PortNumber, Status);
316 return Status;
317 }
318
321
322 KeInitializeDpc(&PortData->Worker.Dpc, AtaPortWorkerSignalDpc, PortData);
324 KeInitializeSpinLock(&PortData->Worker.Lock);
326
329#if DBG
330 PortData->Worker.InternalRequest.Signature = ATA_DEVICE_REQUEST_SIGNATURE;
331#endif
332
333 Status = AtaFdoCreatePortThread(PortData);
334 if (!NT_SUCCESS(Status))
335 {
336 ERR("CH %lu: Failed to create port thread 0x%lx\n", PortData->PortNumber, Status);
337 return Status;
338 }
339
340 Status = AtaFdoCreateSymLinks(ChanExt);
341 if (!NT_SUCCESS(Status))
342 {
343 ERR("CH %lu: Failed to create symbolic links 0x%lx\n", PortData->PortNumber, Status);
344 return Status;
345 }
346
348
349 Status = IoRegisterDeviceInterface(ChanExt->Common.Self,
350 &GUID_DEVINTERFACE_STORAGEPORT,
351 NULL,
352 &ChanExt->StorageInterfaceName);
353 if (NT_SUCCESS(Status))
354 {
355 INFO("InterfaceName: '%wZ'\n", &ChanExt->StorageInterfaceName);
356
357 Status = IoSetDeviceInterfaceState(&ChanExt->StorageInterfaceName, TRUE);
358 if (!NT_SUCCESS(Status))
359 {
360 RtlFreeUnicodeString(&ChanExt->StorageInterfaceName);
361 ChanExt->StorageInterfaceName.Buffer = NULL;
362 }
363 }
364
365 *ChannelInterface.PortContext = PortData;
366 *ChannelInterface.PortNotification = AtaPortNotification;
367 *ChannelInterface.Slots = PortData->Slots;
368
369 Status = IoInitializeTimer(ChanExt->Common.Self, AtaPortIoTimer, PortData);
370 if (!NT_SUCCESS(Status))
371 return Status;
372
373 IoStartTimer(ChanExt->Common.Self);
375
376 Status = PortData->AttachChannel(PortData->ChannelContext, TRUE);
377 if (!NT_SUCCESS(Status))
378 {
379 ERR("CH %lu: Failed to attach channel %lx\n", PortData->PortNumber, Status);
380 return Status;
381 }
383
384 return STATUS_SUCCESS;
385}
386
387static
388CODE_SEG("PAGE")
389VOID
392{
393 PATAPORT_PORT_DATA PortData = &ChanExt->PortData;
394
395 PAGED_CODE();
396
397 if (PortData->AttachChannel)
398 {
399 PortData->AttachChannel(PortData->ChannelContext, FALSE);
400 PortData->AttachChannel = NULL;
401 }
402}
403
404static
405CODE_SEG("PAGE")
409 _In_ PIRP Irp)
410{
411 PAGED_CODE();
412
413 AtaFdoDetachChannel(ChanExt);
414
415 if (ChanExt->StorageInterfaceName.Buffer)
416 IoSetDeviceInterfaceState(&ChanExt->StorageInterfaceName, FALSE);
417
418 return STATUS_SUCCESS;
419}
420
421static
422CODE_SEG("PAGE")
426 _In_ PIRP Irp,
427 _In_ BOOLEAN FinalRemove)
428{
430
431 PAGED_CODE();
432
433 if (ChanExt->StorageInterfaceName.Buffer)
434 {
435 IoSetDeviceInterfaceState(&ChanExt->StorageInterfaceName, FALSE);
436
437 RtlFreeUnicodeString(&ChanExt->StorageInterfaceName);
438 ChanExt->StorageInterfaceName.Buffer = NULL;
439 }
440
442
443 if (ChanExt->PortData.PortFlags & PORT_FLAG_IO_TIMER_ACTIVE)
444 {
445 IoStopTimer(ChanExt->Common.Self);
446 ChanExt->PortData.PortFlags &= ~PORT_FLAG_IO_TIMER_ACTIVE;
447 }
448
449 if (ChanExt->PortData.PortFlags & PORT_FLAG_CHANNEL_ATTACHED)
450 {
451 AtaFdoDetachChannel(ChanExt);
452 ChanExt->PortData.PortFlags &= ~PORT_FLAG_CHANNEL_ATTACHED;
453 }
454
455 if (FinalRemove)
456 {
457 ATA_SCSI_ADDRESS AtaScsiAddress;
458
459 IoReleaseRemoveLockAndWait(&ChanExt->Common.RemoveLock, Irp);
460
461 AtaScsiAddress.AsULONG = 0;
462 while (TRUE)
463 {
465
466 DevExt = AtaFdoFindNextDeviceByPath(ChanExt, &AtaScsiAddress, TRUE, NULL);
467 if (!DevExt)
468 break;
469
471 AtaPdoFreeDevice(DevExt);
472 }
473
474 AtaFdoRemoveSymLinks(ChanExt);
475
476 if (ChanExt->PortData.LocalBuffer)
477 {
478 MmFreeContiguousMemorySpecifyCache(ChanExt->PortData.LocalBuffer,
481 ChanExt->PortData.LocalBuffer = NULL;
482 }
483
484 if (ChanExt->PortData.ReservedVaSpace)
485 {
486 MmFreeMappingAddress(ChanExt->PortData.ReservedVaSpace, ATAPORT_TAG);
487 ChanExt->PortData.ReservedVaSpace = NULL;
488 }
489
490 Irp->IoStatus.Status = STATUS_SUCCESS;
492 Status = IoCallDriver(ChanExt->Common.LowerDeviceObject, Irp);
493
494 IoDetachDevice(ChanExt->Common.LowerDeviceObject);
495 IoDeleteDevice(ChanExt->Common.Self);
496 }
497 else
498 {
500 Status = IoCallDriver(ChanExt->Common.LowerDeviceObject, Irp);
501
502 IoReleaseRemoveLock(&ChanExt->Common.RemoveLock, Irp);
503 }
504
505 return Status;
506}
507
508CODE_SEG("PAGE")
513{
515 PIO_STACK_LOCATION IoStack;
516
517 PAGED_CODE();
518
519 INFO("(%p, %p) Ch.%lu %s\n",
520 ChanExt->Common.Self,
521 Irp,
522 ChanExt->DeviceObjectNumber,
524
525 Status = IoAcquireRemoveLock(&ChanExt->Common.RemoveLock, Irp);
526 if (!NT_SUCCESS(Status))
527 {
528 Irp->IoStatus.Status = Status;
530
531 return Status;
532 }
533
535 switch (IoStack->MinorFunction)
536 {
538 {
539 if (!NT_VERIFY(IoForwardIrpSynchronously(ChanExt->Common.LowerDeviceObject, Irp)))
540 {
542 goto CompleteIrp;
543 }
544 Status = Irp->IoStatus.Status;
545 if (!NT_SUCCESS(Status))
546 goto CompleteIrp;
547
548 Status = AtaFdoStartDevice(ChanExt,
549 IoStack->Parameters.
550 StartDevice.AllocatedResourcesTranslated);
551 goto CompleteIrp;
552 }
553
555 Status = AtaFdoStopDevice(ChanExt, Irp);
556 break;
557
560 return AtaFdoRemoveDevice(ChanExt,
561 Irp,
562 (IoStack->MinorFunction == IRP_MN_REMOVE_DEVICE));
563
565 Status = AtaPnpQueryPnpDeviceState(&ChanExt->Common, Irp);
566 break;
567
569 {
570 if (IoStack->Parameters.QueryDeviceRelations.Type != BusRelations)
571 break;
572
574 if (!NT_SUCCESS(Status))
575 goto CompleteIrp;
576
577 Irp->IoStatus.Status = Status;
578 break;
579 }
580
582 Status = AtaPnpQueryDeviceUsageNotification(&ChanExt->Common, Irp);
583 break;
584
589 Irp->IoStatus.Status = STATUS_SUCCESS;
590 break;
591
592 default:
593 break;
594 }
595
597 Status = IoCallDriver(ChanExt->Common.LowerDeviceObject, Irp);
598
599 IoReleaseRemoveLock(&ChanExt->Common.RemoveLock, Irp);
600
601 return Status;
602
604 Irp->IoStatus.Status = Status;
606
607 IoReleaseRemoveLock(&ChanExt->Common.RemoveLock, Irp);
608
609 return Status;
610}
611
616 _In_ ATA_SCSI_ADDRESS AtaScsiAddress,
617 _In_ PVOID ReferenceTag)
618{
621 KIRQL OldLevel;
623
624 KeAcquireSpinLock(&ChanExt->PdoListLock, &OldLevel);
625
626 for (Entry = ChanExt->PdoList.Next; Entry != NULL; Entry = Entry->Next)
627 {
629
630 if (DevExt->Device.AtaScsiAddress.AsULONG != AtaScsiAddress.AsULONG)
631 continue;
632
633 if (DevExt->ReportedMissing || DevExt->RemovalPending)
634 continue;
635
636 if (ReferenceTag)
637 {
638 Status = IoAcquireRemoveLock(&DevExt->Common.RemoveLock, ReferenceTag);
639 if (!NT_SUCCESS(Status))
640 break;
641 }
642
643 Result = DevExt;
644 break;
645 }
646
647 KeReleaseSpinLock(&ChanExt->PdoListLock, OldLevel);
648
649 return Result;
650}
651
656 _Inout_ PATA_SCSI_ADDRESS AtaScsiAddress,
657 _In_ BOOLEAN SearchRemoveDev,
658 _In_ PVOID ReferenceTag)
659{
662 KIRQL OldLevel;
664
665 KeAcquireSpinLock(&ChanExt->PdoListLock, &OldLevel);
666
667 for (Entry = ChanExt->PdoList.Next; Entry != NULL; Entry = Entry->Next)
668 {
670
671 if (DevExt->Device.AtaScsiAddress.AsULONG <= AtaScsiAddress->AsULONG)
672 continue;
673
674 if (DevExt->ReportedMissing)
675 continue;
676
677 if (!SearchRemoveDev && DevExt->RemovalPending)
678 continue;
679
680 *AtaScsiAddress = DevExt->Device.AtaScsiAddress;
681
682 if (ReferenceTag)
683 {
684 Status = IoAcquireRemoveLock(&DevExt->Common.RemoveLock, ReferenceTag);
685 if (!NT_SUCCESS(Status))
686 continue;
687 }
688 Result = DevExt;
689 break;
690 }
691
692 KeReleaseSpinLock(&ChanExt->PdoListLock, OldLevel);
693
694 return Result;
695}
696
698VOID
702 _In_ BOOLEAN DoInsert)
703{
704 PSINGLE_LIST_ENTRY Entry, PrevEntry;
705 KIRQL OldLevel;
706 ULONG Address = DevExt->Device.AtaScsiAddress.AsULONG;
707
708 PAGED_CODE();
709
710 KeAcquireSpinLock(&ChanExt->PdoListLock, &OldLevel);
711
712 for (Entry = ChanExt->PdoList.Next, PrevEntry = NULL;
713 Entry != NULL;
714 Entry = Entry->Next)
715 {
716 PATAPORT_DEVICE_EXTENSION CurrentDevExt;
717
718 CurrentDevExt = CONTAINING_RECORD(Entry, ATAPORT_DEVICE_EXTENSION, ListEntry);
719
720 if (DoInsert)
721 {
722 if (CurrentDevExt->Device.AtaScsiAddress.AsULONG > Address)
723 break;
724 }
725 else
726 {
727 if (CurrentDevExt->Device.AtaScsiAddress.AsULONG == Address)
728 break;
729 }
730
731 PrevEntry = Entry;
732 }
733
734 /* The device list is ordered by SCSI address (Path:Target:Lun), smallest first */
735 if (PrevEntry)
736 {
737 /* Before the current entry */
738 if (DoInsert)
739 {
740 DevExt->ListEntry.Next = PrevEntry->Next;
741 PrevEntry->Next = &DevExt->ListEntry;
742 }
743 else
744 {
745 PrevEntry->Next = DevExt->ListEntry.Next;
746 }
747 }
748 else
749 {
750 /* In the beginning */
751 if (DoInsert)
752 PushEntryList(&ChanExt->PdoList, &DevExt->ListEntry);
753 else
754 PopEntryList(&DevExt->ListEntry);
755 }
756
757 KeReleaseSpinLock(&ChanExt->PdoListLock, OldLevel);
758}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define PAGED_CODE()
#define CODE_SEG(...)
#define VOID
Definition: acefi.h:82
unsigned char BOOLEAN
Definition: actypes.h:127
#define PCIIDEX_INTERFACE_VERSION
Definition: ata_shared.h:12
#define ATA_CHANNEL_FLAG_IS_EXTERNAL
Definition: ata_shared.h:536
#define ATA_CHANNEL_FLAG_PIO_VIA_DMA
Definition: ata_shared.h:535
#define ATA_CHANNEL_FLAG_PIO_FOR_LBA48_XFER
Definition: ata_shared.h:539
#define ATA_CHANNEL_FLAG_NCQ
Definition: ata_shared.h:537
#define ATA_CHANNEL_FLAG_IS_AHCI
Definition: ata_shared.h:538
#define PIO_ALL
Definition: ata_user.h:19
#define DD_ATA_REG_MAX_TARGET_ID
Definition: ata_user.h:13
NTSTATUS AtaPnpQueryPnpDeviceState(_In_ PATAPORT_COMMON_EXTENSION CommonExt, _In_ PIRP Irp)
Definition: atapi.c:555
VOID AtaSetPortRegistryKey(_In_ PATAPORT_CHANNEL_EXTENSION ChanExt, _In_ PCWSTR KeyName, _In_ ULONG KeyValue)
Definition: atapi.c:236
NTSTATUS AtaPnpQueryInterface(_In_ PATAPORT_COMMON_EXTENSION CommonExt, _In_ const GUID *Guid, _Out_ PVOID Interface, _In_ ULONG Version, _In_ ULONG Size)
Definition: atapi.c:396
NTSTATUS AtaPnpQueryDeviceUsageNotification(_In_ PATAPORT_COMMON_EXTENSION CommonExt, _In_ PIRP Irp)
Definition: atapi.c:503
IO_TIMER_ROUTINE AtaPortIoTimer
Definition: atapi.h:938
#define PORT_FLAG_PIO_FOR_LBA48_XFER
Definition: atapi.h:345
#define PORT_FLAG_PIO_ONLY
Definition: atapi.h:344
#define PORT_FLAG_NCQ
Definition: atapi.h:339
#define PORT_FLAG_EXIT_THREAD
Definition: atapi.h:346
#define PORT_FLAG_PIO_VIA_DMA
Definition: atapi.h:337
VOID AtaPdoFreeDevice(_In_ PATAPORT_DEVICE_EXTENSION DevExt)
Definition: pdo.c:658
#define PORT_INT_FLAG_IS_IO_ACTIVE
Definition: atapi.h:360
KDEFERRED_ROUTINE AtaPortWorkerSignalDpc
Definition: atapi.h:879
#define DECLARE_PAGED_WSTRING(v, n)
Definition: atapi.h:162
#define PORT_FLAG_SYMLINK_CREATED
Definition: atapi.h:341
#define PORT_FLAG_IO_TIMER_ACTIVE
Definition: atapi.h:342
KSTART_ROUTINE AtaPortWorkerThread
Definition: atapi.h:878
NTSTATUS AtaFdoQueryBusRelations(_In_ PATAPORT_CHANNEL_EXTENSION ChanExt, _In_ PIRP Irp)
Definition: enum.c:566
#define NUM_TO_BITMAP(num)
Definition: atapi.h:179
#define ATA_RESERVED_PAGES
Definition: atapi.h:200
KDEFERRED_ROUTINE AtaStorageNotificationlDpc
Definition: atapi.h:655
#define PORT_FLAG_IS_SIMPLEX
Definition: atapi.h:336
DECLSPEC_NOINLINE_FROM_PAGED VOID AtaReqFlushDeviceQueue(_In_ PATAPORT_IO_CONTEXT Device)
Definition: scsi.c:1451
#define PORT_FLAG_IS_AHCI
Definition: atapi.h:340
#define PORT_FLAG_CHANNEL_ATTACHED
Definition: atapi.h:343
REQUEST_COMPLETION_ROUTINE AtaPortCompleteInternalRequest
Definition: atapi.h:880
PORT_NOTIFICATION AtaPortNotification
Definition: atapi.h:881
DECLSPEC_NOINLINE_FROM_PAGED VOID AtaPortSignalWorkerThread(_In_ PATAPORT_PORT_DATA PortData)
Definition: portstate.c:963
#define PORT_FLAG_IS_EXTERNAL
Definition: atapi.h:338
#define ATAPORT_TAG
Definition: atapi.h:171
#define ATA_LOCAL_BUFFER_SIZE
Definition: atapi.h:205
LONG NTSTATUS
Definition: precomp.h:26
@ ScsiAdapter
Definition: arcname.c:40
#define ERR(fmt,...)
Definition: precomp.h:57
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
PVOID NTAPI MmAllocateContiguousMemorySpecifyCache(IN SIZE_T NumberOfBytes, IN PHYSICAL_ADDRESS LowestAcceptableAddress OPTIONAL, IN PHYSICAL_ADDRESS HighestAcceptableAddress, IN PHYSICAL_ADDRESS BoundaryAddressMultiple OPTIONAL, IN MEMORY_CACHING_TYPE CacheType OPTIONAL)
Definition: contmem.c:574
VOID NTAPI MmFreeContiguousMemorySpecifyCache(IN PVOID BaseAddress, IN SIZE_T NumberOfBytes, IN MEMORY_CACHING_TYPE CacheType)
Definition: contmem.c:666
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:712
FORCEINLINE PCHAR GetIRPMinorFunctionString(UCHAR MinorFunction)
Definition: driverdbg.h:13
#define L(x)
Definition: resources.c:13
#define INFO
Definition: debug.h:89
VOID CompleteIrp(IN PIRP Irp, IN NTSTATUS Status, IN ULONG_PTR Information)
Definition: pnp.c:12
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
Status
Definition: gdiplustypes.h:25
HRESULT Next([in] ULONG celt, [out, size_is(celt), length_is(*pceltFetched)] STATPROPSETSTG *rgelt, [out] ULONG *pceltFetched)
PCONFIGURATION_INFORMATION NTAPI IoGetConfigurationInformation(VOID)
Returns a pointer to the I/O manager's global configuration information structure.
Definition: iorsrce.c:998
NTSTATUS NTAPI IoInitializeTimer(IN PDEVICE_OBJECT DeviceObject, IN PIO_TIMER_ROUTINE TimerRoutine, IN PVOID Context)
Definition: iotimer.c:92
VOID NTAPI IoStartTimer(IN PDEVICE_OBJECT DeviceObject)
Definition: iotimer.c:133
VOID NTAPI IoStopTimer(PDEVICE_OBJECT DeviceObject)
Definition: iotimer.c:164
#define ASSERT(a)
Definition: mode.c:44
_Out_ PNDIS_HANDLE _Out_ PUINT _In_ PNDIS_STRING _In_ NDIS_PHYSICAL_ADDRESS HighestAcceptableAddress
Definition: ndis.h:3230
#define KernelMode
Definition: asm.h:38
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
static BOOL StartDevice(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DevInfoData OPTIONAL, IN BOOL bEnable, IN DWORD HardwareProfile OPTIONAL, OUT BOOL *bNeedReboot OPTIONAL)
Definition: wizard.c:173
#define _Inout_
Definition: no_sal2.h:162
#define _In_
Definition: no_sal2.h:158
#define THREAD_ALL_ACCESS
Definition: nt_native.h:1342
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define RTL_BITS_OF(sizeOfArg)
Definition: ntbasedef.h:680
@ NotificationEvent
#define RTL_CONSTANT_OBJECT_ATTRIBUTES(n, a)
#define IRP_MN_SURPRISE_REMOVAL
Definition: ntifs_ex.h:408
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
VOID NTAPI IoDetachDevice(IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:1297
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1252
NTSTATUS NTAPI IoRegisterDeviceInterface(IN PDEVICE_OBJECT PhysicalDeviceObject, IN CONST GUID *InterfaceClassGuid, IN PUNICODE_STRING ReferenceString OPTIONAL, OUT PUNICODE_STRING SymbolicLinkName)
Definition: deviface.c:1437
NTSTATUS NTAPI IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
Definition: deviface.c:1793
#define IoCompleteRequest
Definition: irp.c:1240
BOOLEAN NTAPI IoForwardIrpSynchronously(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1625
#define IoCallDriver
Definition: irp.c:1225
PHYSICAL_ADDRESS NTAPI MmGetPhysicalAddress(IN PVOID Address)
Definition: stubs.c:685
NTSTATUS NTAPI PsCreateSystemThread(OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN HANDLE ProcessHandle, IN PCLIENT_ID ClientId, IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext)
Definition: thread.c:602
NTSTRSAFEVAPI RtlStringCbPrintfW(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1173
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
short WCHAR
Definition: pedump.c:58
static WCHAR Address[46]
Definition: ping.c:68
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
Entry
Definition: section.c:5210
#define DECLSPEC_NOINLINE_FROM_PAGED
#define STATUS_SUCCESS
Definition: shellext.h:65
static NTSTATUS AtaFdoRemoveDevice(_In_ PATAPORT_CHANNEL_EXTENSION ChanExt, _In_ PIRP Irp, _In_ BOOLEAN FinalRemove)
Definition: fdo.c:424
NTSTATUS AtaFdoPnp(_In_ PATAPORT_CHANNEL_EXTENSION ChanExt, _Inout_ PIRP Irp)
Definition: fdo.c:510
static NTSTATUS AtaFdoStopDevice(_In_ PATAPORT_CHANNEL_EXTENSION ChanExt, _In_ PIRP Irp)
Definition: fdo.c:407
static NTSTATUS AtaFdoAllocateLocalBuffer(_In_ PATAPORT_PORT_DATA PortData)
Definition: fdo.c:93
static NTSTATUS AtaFdoCreateSymLinks(_In_ PATAPORT_CHANNEL_EXTENSION ChanExt)
Definition: fdo.c:22
static VOID AtaFdoRemoveSymLinks(_In_ PATAPORT_CHANNEL_EXTENSION ChanExt)
Definition: fdo.c:193
static VOID AtaFdoDetachChannel(_In_ PATAPORT_CHANNEL_EXTENSION ChanExt)
Definition: fdo.c:390
NTSTATUS AtaFdoStartDevice(_In_ PATAPORT_CHANNEL_EXTENSION ChanExt, _In_ PCM_RESOURCE_LIST ResourcesTranslated)
Definition: fdo.c:229
static VOID AtaFdoDestroyPortThread(_In_ PATAPORT_CHANNEL_EXTENSION ChanExt)
Definition: fdo.c:170
static NTSTATUS AtaFdoCreatePortThread(_In_ PATAPORT_PORT_DATA PortData)
Definition: fdo.c:129
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
DECLSPEC_NOINLINE_FROM_PAGED PATAPORT_DEVICE_EXTENSION AtaFdoFindDeviceByPath(_In_ PATAPORT_CHANNEL_EXTENSION ChanExt, _In_ ATA_SCSI_ADDRESS AtaScsiAddress, _In_ PVOID ReferenceTag)
Definition: fdo.c:614
DECLSPEC_NOINLINE_FROM_PAGED VOID AtaFdoDeviceListInsert(_In_ PATAPORT_CHANNEL_EXTENSION ChanExt, _In_ PATAPORT_DEVICE_EXTENSION DevExt, _In_ BOOLEAN DoInsert)
Definition: fdo.c:699
IO_REMOVE_LOCK RemoveLock
Definition: atapi.h:434
ATAPORT_IO_CONTEXT Device
Definition: atapi.h:457
ATAPORT_COMMON_EXTENSION Common
Definition: atapi.h:455
ATA_SCSI_ADDRESS AtaScsiAddress
Definition: atapi.h:100
PCHANNEL_SET_MODE SetTransferMode
Definition: atapi.h:386
PVOID ChannelContext
Definition: atapi.h:348
PCHANNEL_ENUMERATE_CHANNEL EnumerateChannel
Definition: atapi.h:384
ULONG MaximumPhysicalPages
Definition: atapi.h:393
ULONG LastUsedSlot
Definition: atapi.h:367
PDMA_ADAPTER DmaAdapter
Definition: atapi.h:353
PDEVICE_OBJECT ChannelObject
Definition: atapi.h:354
ULONG MaximumTransferLength
Definition: atapi.h:392
ULONG FreeSlotsBitmap
Definition: atapi.h:366
PCHANNEL_IDENTIFY_DEVICE IdentifyDevice
Definition: atapi.h:385
PCHANNEL_PREPARE_PRD_TABLE PreparePrdTable
Definition: atapi.h:350
PCHANNEL_SET_DEVICE_DATA SetDeviceData
Definition: atapi.h:387
PATA_DEVICE_REQUEST Slots[MAX_SLOTS]
Definition: atapi.h:355
KEVENT QueueStoppedEvent
Definition: atapi.h:391
PCHANNEL_GET_INIT_TASK_FILE GetInitTaskFile
Definition: atapi.h:388
PCHANNEL_START_IO StartIo
Definition: atapi.h:352
PCHANNEL_ABORT_CHANNEL AbortChannel
Definition: atapi.h:382
PCHANNEL_RESET_CHANNEL ResetChannel
Definition: atapi.h:383
volatile LONG InterruptFlags
Definition: atapi.h:359
PCHANNEL_PREPARE_IO PrepareIo
Definition: atapi.h:351
PCHANNEL_DOWNGRADE_INTERFACE_SPEED DowngradeInterfaceSpeed
Definition: atapi.h:389
ULONG PortNumber
Definition: atapi.h:396
ULONG MaxSlotsBitmap
Definition: atapi.h:397
PKINTERRUPT InterruptObject
Definition: atapi.h:357
ULONG PortFlags
Definition: atapi.h:335
ATA_WORKER_CONTEXT Worker
Definition: atapi.h:400
PCONTROLLER_ATTACH_CHANNEL AttachChannel
Definition: atapi.h:390
PCHANNEL_ALLOCATE_SLOT AllocateSlot
Definition: atapi.h:349
ULONG QueueDepth
Definition: atapi.h:395
LIST_ENTRY PortQueueList
Definition: atapi.h:364
PCONTROLLER_OBJECT HwSyncObject
Definition: atapi.h:381
ULONG MaxTargetId
Definition: atapi.h:394
PVOID ReservedVaSpace
Definition: atapi.h:380
PREQUEST_COMPLETION_ROUTINE Complete
Definition: ata_shared.h:230
ATA_DEVICE_REQUEST InternalRequest
Definition: atapi.h:291
KEVENT EnumerationEvent
Definition: atapi.h:293
PKTHREAD Thread
Definition: atapi.h:295
KEVENT CompletionEvent
Definition: atapi.h:290
KSPIN_LOCK Lock
Definition: atapi.h:273
KDPC NotificationDpc
Definition: atapi.h:294
union _IO_STACK_LOCATION::@1696 Parameters
struct _IO_STACK_LOCATION::@4366::@4391 QueryDeviceRelations
Channel interface with the PCIIDEX driver.
Definition: ata_shared.h:502
PPORT_NOTIFICATION * PortNotification
Definition: ata_shared.h:542
PCHANNEL_SET_MODE SetTransferMode
Definition: ata_shared.h:526
PCHANNEL_ALLOCATE_SLOT AllocateSlot
Definition: ata_shared.h:527
PCHANNEL_RESET_CHANNEL ResetChannel
Definition: ata_shared.h:523
PCHANNEL_DOWNGRADE_INTERFACE_SPEED DowngradeInterfaceSpeed
Definition: ata_shared.h:521
PCHANNEL_IDENTIFY_DEVICE IdentifyDevice
Definition: ata_shared.h:525
PCHANNEL_GET_INIT_TASK_FILE GetInitTaskFile
Definition: ata_shared.h:520
PCHANNEL_ABORT_CHANNEL AbortChannel
Definition: ata_shared.h:522
PCHANNEL_SET_DEVICE_DATA SetDeviceData
Definition: ata_shared.h:519
PCHANNEL_START_IO StartIo
Definition: ata_shared.h:530
PCONTROLLER_OBJECT HwSyncObject
Definition: ata_shared.h:531
PCHANNEL_PREPARE_IO PrepareIo
Definition: ata_shared.h:529
PCONTROLLER_ATTACH_CHANNEL AttachChannel
Definition: ata_shared.h:511
PCHANNEL_PREPARE_PRD_TABLE PreparePrdTable
Definition: ata_shared.h:528
PATA_DEVICE_REQUEST ** Slots
Definition: ata_shared.h:543
PDEVICE_OBJECT ChannelObject
Definition: ata_shared.h:533
PCHANNEL_ENUMERATE_CHANNEL EnumerateChannel
Definition: ata_shared.h:524
Definition: ntbasedef.h:640
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:641
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
ULONG AsULONG
Definition: atapi.h:69
LONGLONG QuadPart
Definition: typedefs.h:114
_In_ WDFCMRESLIST _In_ WDFCMRESLIST ResourcesTranslated
Definition: wdfdevice.h:891
_In_ UCHAR _In_ UCHAR MinorFunction
Definition: wdfdevice.h:1705
_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
#define IoAcquireRemoveLock(RemoveLock, Tag)
#define IoReleaseRemoveLockAndWait(_RemoveLock, _Tag)
Definition: iofuncs.h:2774
#define IoReleaseRemoveLock(_RemoveLock, _Tag)
Definition: iofuncs.h:2764
#define IRP_MN_CANCEL_STOP_DEVICE
@ BusRelations
Definition: iotypes.h:2154
#define IRP_MN_QUERY_PNP_DEVICE_STATE
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS PhysicalAddress
Definition: iotypes.h:1098
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define IRP_MN_START_DEVICE
#define IRP_MN_DEVICE_USAGE_NOTIFICATION
#define IRP_MN_REMOVE_DEVICE
#define IRP_MN_QUERY_DEVICE_RELATIONS
#define IRP_MN_QUERY_STOP_DEVICE
#define IRP_MN_CANCEL_REMOVE_DEVICE
#define IRP_MN_STOP_DEVICE
#define IRP_MN_QUERY_REMOVE_DEVICE
@ Executive
Definition: ketypes.h:467
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS _In_ PHYSICAL_ADDRESS _In_opt_ PHYSICAL_ADDRESS BoundaryAddressMultiple
Definition: mmfuncs.h:216
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS LowestAcceptableAddress
Definition: mmfuncs.h:214
@ MmNonCached
Definition: mmtypes.h:129
#define ObDereferenceObject
Definition: obfuncs.h:203
FORCEINLINE VOID PushEntryList(_Inout_ PSINGLE_LIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PSINGLE_LIST_ENTRY Entry)
Definition: rtlfuncs.h:256
#define NT_VERIFY(exp)
Definition: rtlfuncs.h:3304
FORCEINLINE PSINGLE_LIST_ENTRY PopEntryList(_Inout_ PSINGLE_LIST_ENTRY ListHead)
Definition: rtlfuncs.h:243