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

Go to the source code of this file.

Functions

PUCHAR AtaCopyIdStringUnsafe (_Out_writes_bytes_all_(Length) PUCHAR Destination, _In_reads_bytes_(Length) PUCHAR Source, _In_ ULONG Length)
 
PCHAR AtaCopyIdStringSafe (_Out_writes_bytes_all_(MaxLength) PCHAR Destination, _In_reads_bytes_(MaxLength) PUCHAR Source, _In_ ULONG MaxLength, _In_ CHAR DefaultCharacter)
 
VOID AtaSwapIdString (_Inout_updates_bytes_(WordCount *sizeof(USHORT)) PVOID Buffer, _In_range_(>, 0) ULONG WordCount)
 
static PCHAR AtaTrimIdString (_In_ _Post_z_ PCHAR Start, _In_ PCHAR End)
 
static VOID AtaPdoFillIdentificationStrings (_In_ PATAPORT_DEVICE_EXTENSION DevExt)
 
VOID AtaDeviceSetAddressingMode (_In_ PATAPORT_DEVICE_EXTENSION DevExt)
 
static VOID AtaDeviceEnableQueuedCommands (_In_ PATAPORT_DEVICE_EXTENSION DevExt)
 
static BOOLEAN AtaDeviceIsSuperFloppy (_In_ PATAPORT_DEVICE_EXTENSION DevExt)
 
static VOID AtaPdoInit (_In_ PATAPORT_CHANNEL_EXTENSION ChanExt, _In_ PATAPORT_DEVICE_EXTENSION DevExt)
 
static ULONG AtaFdoQueryDeviceCount (_In_ PATAPORT_PORT_DATA PortData)
 
static ATA_DEVICE_STATUS AtaFdoQueryDeviceStatus (_In_ PATAPORT_PORT_DATA PortData, _In_ PATAPORT_DEVICE_EXTENSION DevExt, _In_ ATA_PORT_ACTION Action)
 
static VOID AtaFdoEnumeratePort (_In_ PATAPORT_CHANNEL_EXTENSION ChanExt)
 
static VOID AtaFdoInitializeDeviceRelations (_In_ PATAPORT_CHANNEL_EXTENSION ChanExt, _In_ PDEVICE_RELATIONS DeviceRelations)
 
NTSTATUS AtaFdoQueryBusRelations (_In_ PATAPORT_CHANNEL_EXTENSION ChanExt, _In_ PIRP Irp)
 

Function Documentation

◆ AtaCopyIdStringSafe()

PCHAR AtaCopyIdStringSafe ( _Out_writes_bytes_all_(MaxLength) PCHAR  Destination,
_In_reads_bytes_(MaxLength) PUCHAR  Source,
_In_ ULONG  MaxLength,
_In_ CHAR  DefaultCharacter 
)

Definition at line 35 of file enum.c.

40{
41 PCHAR Dest = Destination;
42
43 PAGED_CODE();
44
45 while (MaxLength != 0)
46 {
47 const UCHAR Char = *Source;
48
49 /* Only characters from space to tilde are allowed in an ID */
50 if (Char > ' ' && Char <= '~' && Char != ',')
51 *Dest = Char;
52 else
53 *Dest = DefaultCharacter;
54
55 ++Source;
56 ++Dest;
57 --MaxLength;
58 }
59
60 return Dest;
61}
#define PAGED_CODE()
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3169
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:3051
unsigned char UCHAR
Definition: typedefs.h:53
char * PCHAR
Definition: typedefs.h:51

Referenced by AtaCreateAtapiStandardInquiryData(), AtaPdoFillIdentificationStrings(), and AtaPdoQueryId().

◆ AtaCopyIdStringUnsafe()

PUCHAR AtaCopyIdStringUnsafe ( _Out_writes_bytes_all_(Length) PUCHAR  Destination,
_In_reads_bytes_(Length) PUCHAR  Source,
_In_ ULONG  Length 
)

Definition at line 15 of file enum.c.

19{
20 ULONG i;
21
22 ASSUME((Length >= sizeof(USHORT)) && (Length % sizeof(USHORT)) == 0);
23
24 /* Copy the ATA string and swap it */
25 for (i = 0; i < Length; i += sizeof(USHORT))
26 {
27 Destination[i] = Source[i + 1];
28 Destination[i + 1] = Source[i];
29 }
30
31 return &Destination[i - 1];
32}
#define ASSUME(cond)
Definition: atapi.h:165
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
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
unsigned short USHORT
Definition: pedump.c:61
uint32_t ULONG
Definition: typedefs.h:59

Referenced by AtaCreateStandardInquiryData(), AtaDeviceIsXboxDrive(), AtaReqScsiInquiryDeviceIdentifiers(), and AtaReqScsiInquirySerialNumber().

◆ AtaDeviceEnableQueuedCommands()

static VOID AtaDeviceEnableQueuedCommands ( _In_ PATAPORT_DEVICE_EXTENSION  DevExt)
static

Definition at line 267 of file enum.c.

269{
270 ULONG DeviceQueueDepth;
271
272 PAGED_CODE();
273
274 DeviceQueueDepth = AtaDevQueueDepth(&DevExt->IdentifyDeviceData);
275 if (DeviceQueueDepth == 0)
276 return;
277
278 /* Do not set the queue depth to larger than the HBA can handle */
279 DeviceQueueDepth = min(DeviceQueueDepth, DevExt->Device.PortData->QueueDepth);
280
281 DevExt->Device.TransportFlags |= DeviceQueueDepth << DEVICE_QUEUE_DEPTH_SHIFT;
282
283 DevExt->Device.DeviceFlags |= DEVICE_NCQ;
284
285 INFO("NCQ enabled, queue depth %lu/%lu\n",
286 DeviceQueueDepth,
287 DevExt->Device.PortData->QueueDepth);
288}
#define DEVICE_QUEUE_DEPTH_SHIFT
Definition: ata_shared.h:171
#define DEVICE_NCQ
Definition: atapi.h:86
#define INFO
Definition: debug.h:89
FORCEINLINE ULONG AtaDevQueueDepth(_In_ PIDENTIFY_DEVICE_DATA IdentifyData)
#define min(a, b)
Definition: monoChain.cc:55

Referenced by AtaPdoInit().

◆ AtaDeviceIsSuperFloppy()

static BOOLEAN AtaDeviceIsSuperFloppy ( _In_ PATAPORT_DEVICE_EXTENSION  DevExt)
static

Definition at line 293 of file enum.c.

295{
296 PAGED_CODE();
297
298 if (DevExt->InquiryData.DeviceType == DIRECT_ACCESS_DEVICE)
299 {
300 /* Look for ATAPI SuperDisk drives. For example, 'MATSHITA LS-120 COSM 03' */
301 return (strstr(DevExt->FriendlyName, " LS-120") ||
302 strstr(DevExt->FriendlyName, " LS-240"));
303 }
304
305 return FALSE;
306}
#define DIRECT_ACCESS_DEVICE
Definition: cdrw_hw.h:1144
#define FALSE
Definition: types.h:117
_ACRTIMP char *__cdecl strstr(const char *, const char *)
Definition: string.c:3415

Referenced by AtaPdoInit().

◆ AtaDeviceSetAddressingMode()

VOID AtaDeviceSetAddressingMode ( _In_ PATAPORT_DEVICE_EXTENSION  DevExt)

Definition at line 182 of file enum.c.

184{
185 PIDENTIFY_DEVICE_DATA IdentifyData = &DevExt->IdentifyDeviceData;
186 ULONG64 TotalSectors;
187
188 DevExt->Device.DeviceFlags &= ~(DEVICE_LBA_MODE | DEVICE_LBA48 | DEVICE_HAS_FUA);
189
190 /* Using LBA addressing mode */
191 if (AtaDevHasLbaTranslation(IdentifyData))
192 {
193 DevExt->Device.DeviceFlags |= DEVICE_LBA_MODE;
194
195 if (AtaDevHas48BitAddressFeature(IdentifyData))
196 {
197 /* Using LBA48 addressing mode */
198 TotalSectors = AtaDevUserAddressableSectors48Bit(IdentifyData);
199 ASSERT(TotalSectors <= ATA_MAX_LBA_48);
200
201 DevExt->Device.DeviceFlags |= DEVICE_LBA48;
202
203 if (AtaDevHasForceUnitAccessCommands(IdentifyData))
204 DevExt->Device.DeviceFlags |= DEVICE_HAS_FUA;
205 }
206 else
207 {
208 /* Using LBA28 addressing mode */
209 TotalSectors = AtaDevUserAddressableSectors28Bit(IdentifyData);
210 ASSERT(TotalSectors <= ATA_MAX_LBA_28);
211 }
212 }
213 else
214 {
215 USHORT Cylinders, Heads, SectorsPerTrack;
216
217 /* Using CHS addressing mode */
218 if (AtaDevIsCurrentGeometryValid(IdentifyData))
219 {
220 AtaDevCurrentChsTranslation(IdentifyData, &Cylinders, &Heads, &SectorsPerTrack);
221 }
222 else
223 {
224 AtaDevDefaultChsTranslation(IdentifyData, &Cylinders, &Heads, &SectorsPerTrack);
225 }
226 DevExt->Device.Cylinders = Cylinders;
227 DevExt->Device.Heads = Heads;
228 DevExt->Device.SectorsPerTrack = SectorsPerTrack;
229
230 TotalSectors = (ULONG64)Cylinders * Heads * SectorsPerTrack;
231 }
232
233 /*
234 * The sector count can be 0 on faulty devices. It's better to keep
235 * them available in the system to allow
236 * the user to send any command to the drive through the pass-through interface.
237 */
238 if (TotalSectors == 0)
239 {
240 ERR("Unknown geometry\n");
241
242 /* Fix up sector count for the READ CAPACITY command */
243 TotalSectors = 1;
244
245 /* Avoid dividing by zero in READ/WRITE commands */
246 DevExt->Device.SectorsPerTrack = 1;
247 DevExt->Device.Heads = 1;
248 }
249
250 DevExt->Device.TotalSectors = TotalSectors;
251
252 DevExt->Device.SectorSize = AtaDevBytesPerLogicalSector(IdentifyData);
253 ASSERT(DevExt->Device.SectorSize >= ATA_MIN_SECTOR_SIZE);
254 DevExt->Device.SectorSize = max(DevExt->Device.SectorSize, ATA_MIN_SECTOR_SIZE);
255
256 INFO("Total sectors %I64u of size %lu, CHS %u:%u:%u\n",
257 DevExt->Device.TotalSectors,
258 DevExt->Device.SectorSize,
259 DevExt->Device.Cylinders,
260 DevExt->Device.Heads,
261 DevExt->Device.SectorsPerTrack);
262}
#define ATA_MIN_SECTOR_SIZE
256 sectors of 512 bytes (128 kB).
Definition: ata_shared.h:24
#define DEVICE_HAS_FUA
Definition: atapi.h:85
#define DEVICE_LBA48
Definition: atapi.h:84
#define DEVICE_LBA_MODE
Definition: atapi.h:83
#define ERR(fmt,...)
Definition: precomp.h:57
FORCEINLINE VOID AtaDevDefaultChsTranslation(_In_ PIDENTIFY_DEVICE_DATA IdentifyData, _Out_ PUSHORT Cylinders, _Out_ PUSHORT Heads, _Out_ PUSHORT SectorsPerTrack)
Definition: hwidep.h:290
FORCEINLINE ULONG AtaDevBytesPerLogicalSector(_In_ PIDENTIFY_DEVICE_DATA IdentifyData)
Definition: hwidep.h:362
#define ATA_MAX_LBA_48
Definition: hwidep.h:50
FORCEINLINE BOOLEAN AtaDevHas48BitAddressFeature(_In_ PIDENTIFY_DEVICE_DATA IdentifyData)
Definition: hwidep.h:262
FORCEINLINE ULONG64 AtaDevUserAddressableSectors48Bit(_In_ PIDENTIFY_DEVICE_DATA IdentifyData)
Definition: hwidep.h:253
FORCEINLINE BOOLEAN AtaDevHasLbaTranslation(_In_ PIDENTIFY_DEVICE_DATA IdentifyData)
Definition: hwidep.h:235
FORCEINLINE ULONG AtaDevUserAddressableSectors28Bit(_In_ PIDENTIFY_DEVICE_DATA IdentifyData)
Definition: hwidep.h:244
#define ATA_MAX_LBA_28
Definition: hwidep.h:49
FORCEINLINE BOOLEAN AtaDevIsCurrentGeometryValid(_In_ PIDENTIFY_DEVICE_DATA IdentifyData)
Definition: hwidep.h:277
FORCEINLINE VOID AtaDevCurrentChsTranslation(_In_ PIDENTIFY_DEVICE_DATA IdentifyData, _Out_ PUSHORT Cylinders, _Out_ PUSHORT Heads, _Out_ PUSHORT SectorsPerTrack)
Definition: hwidep.h:308
FORCEINLINE BOOLEAN AtaDevHasForceUnitAccessCommands(_In_ PIDENTIFY_DEVICE_DATA IdentifyData)
#define ASSERT(a)
Definition: mode.c:44
unsigned __int64 ULONG64
Definition: imports.h:198
#define max(a, b)
Definition: svc.c:63
_In_ ULONG _In_ ULONG SectorsPerTrack
Definition: iofuncs.h:2071

Referenced by AtaPdoInit(), and AtaReqCompleteReadCapacity().

◆ AtaFdoEnumeratePort()

static VOID AtaFdoEnumeratePort ( _In_ PATAPORT_CHANNEL_EXTENSION  ChanExt)
static

Definition at line 416 of file enum.c.

418{
419 PATAPORT_PORT_DATA PortData = &ChanExt->PortData;
421 BOOLEAN DiscoveredNewDevice = FALSE;
422
423 PAGED_CODE();
424
426
427 for (i = 0; i < DeviceCount; ++i)
428 {
430 ATA_SCSI_ADDRESS AtaScsiAddress;
431 ATA_DEVICE_STATUS EnumStatus;
432
433 AtaScsiAddress = AtaMarshallScsiAddress(PortData->PortNumber, i, 0);
434
435 /* Try to find an existing device */
436 DevExt = AtaFdoFindDeviceByPath(ChanExt, AtaScsiAddress, NULL);
437 if (!DevExt)
438 {
439 DevExt = AtaPdoCreateDevice(ChanExt, AtaScsiAddress);
440 if (!DevExt)
441 {
442 /* We are out of memory, trying to continue process the QBR IRP anyway */
443 ERR("Failed to allocate PDO extension\n");
444 continue;
445 }
446
447 /* Query the last known device type */
448 AtaGetRegistryKey(ChanExt,
449 i,
451 &DevExt->DeviceType,
452 DEV_NONE);
453
454 PortData->Worker.EnumDevExt = DevExt;
455 EnumStatus = AtaFdoQueryDeviceStatus(PortData, DevExt, ACTION_ENUM_DEVICE_NEW);
456 }
457 else
458 {
459 EnumStatus = AtaFdoQueryDeviceStatus(PortData, DevExt, ACTION_ENUM_DEVICE);
460 }
461
462 /* Determine the type of the device */
463 switch (EnumStatus)
464 {
465 /* No device present at this SCSI address */
468 {
470 AtaPdoFreeDevice(DevExt);
471 continue;
472 }
473
474 /* It's the same device still */
476 {
478
479 DevExt->NotPresent = FALSE;
480 continue;
481 }
482
483 /* At this point, we assume that the drive is a new device */
485 {
486 /* Device type has changed because of a hot-plug event */
487 if (!(DevExt->Device.DeviceFlags & DEVICE_UNINITIALIZED))
488 {
489 /* Create a new PDO for the newly hotplugged device */
490 --i; // Retry
491 continue;
492 }
493 break;
494 }
495
496 default:
497 ASSERT(FALSE);
499 }
500
501 AtaPdoInit(ChanExt, DevExt);
502 AtaFdoDeviceListInsert(ChanExt, DevExt, TRUE);
503
504 DiscoveredNewDevice = TRUE;
505 }
506
507 /* Prepare the channel for a new device */
508 if (DiscoveredNewDevice)
510}
unsigned char BOOLEAN
Definition: actypes.h:127
#define DD_ATA_REG_ATA_DEVICE_TYPE
Definition: ata_user.h:11
VOID AtaGetRegistryKey(_In_ PATAPORT_CHANNEL_EXTENSION ChanExt, _In_ UCHAR TargetId, _In_ PCWSTR KeyName, _Out_ PULONG KeyValue, _In_ ULONG DefaultValue)
Definition: atapi.c:113
VOID AtaPdoFreeDevice(_In_ PATAPORT_DEVICE_EXTENSION DevExt)
Definition: pdo.c:658
@ ACTION_PORT_TIMING
Definition: atapi.h:247
@ ACTION_ENUM_DEVICE_NEW
Definition: atapi.h:245
@ ACTION_ENUM_DEVICE
Definition: atapi.h:246
@ DEV_STATUS_FAILED
Definition: atapi.h:258
@ DEV_STATUS_SAME_DEVICE
Definition: atapi.h:257
@ DEV_STATUS_NO_DEVICE
Definition: atapi.h:255
@ DEV_STATUS_NEW_DEVICE
Definition: atapi.h:256
FORCEINLINE ATA_SCSI_ADDRESS AtaMarshallScsiAddress(_In_ ULONG PathId, _In_ ULONG TargetId, _In_ ULONG Lun)
Definition: atapi.h:585
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
PATAPORT_DEVICE_EXTENSION AtaPdoCreateDevice(_In_ PATAPORT_CHANNEL_EXTENSION ChanExt, _In_ ATA_SCSI_ADDRESS AtaScsiAddress)
Definition: pdo.c:685
DECLSPEC_NOINLINE_FROM_PAGED VOID AtaDeviceQueueEvent(_In_ PATAPORT_PORT_DATA PortData, _In_opt_ PATAPORT_DEVICE_EXTENSION DevExt, _In_ ATA_PORT_ACTION Action)
Definition: portstate.c:992
enum _ATA_DEVICE_STATUS ATA_DEVICE_STATUS
#define DEVICE_UNINITIALIZED
Definition: atapi.h:91
DECLSPEC_NOINLINE_FROM_PAGED VOID AtaFdoDeviceListInsert(_In_ PATAPORT_CHANNEL_EXTENSION ChanExt, _In_ PATAPORT_DEVICE_EXTENSION DevExt, _In_ BOOLEAN DoInsert)
Definition: fdo.c:699
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
static VOID AtaPdoInit(_In_ PATAPORT_CHANNEL_EXTENSION ChanExt, _In_ PATAPORT_DEVICE_EXTENSION DevExt)
Definition: enum.c:311
static ULONG AtaFdoQueryDeviceCount(_In_ PATAPORT_PORT_DATA PortData)
Definition: enum.c:378
static ATA_DEVICE_STATUS AtaFdoQueryDeviceStatus(_In_ PATAPORT_PORT_DATA PortData, _In_ PATAPORT_DEVICE_EXTENSION DevExt, _In_ ATA_PORT_ACTION Action)
Definition: enum.c:396
@ DEV_NONE
Definition: hwidep.h:102
ULONG DeviceCount
Definition: mpu401.c:26
#define UNREACHABLE
ATAPORT_IO_CONTEXT Device
Definition: atapi.h:457
ULONG DeviceFlags
Definition: atapi.h:81
ULONG PortNumber
Definition: atapi.h:396
ATA_WORKER_CONTEXT Worker
Definition: atapi.h:400
volatile PATAPORT_DEVICE_EXTENSION EnumDevExt
Definition: atapi.h:275

Referenced by AtaFdoQueryBusRelations().

◆ AtaFdoInitializeDeviceRelations()

static VOID AtaFdoInitializeDeviceRelations ( _In_ PATAPORT_CHANNEL_EXTENSION  ChanExt,
_In_ PDEVICE_RELATIONS  DeviceRelations 
)
static

Definition at line 515 of file enum.c.

518{
520 ATA_SCSI_ADDRESS AtaScsiAddress;
521
522 PAGED_CODE();
523
524 DeviceRelations->Count = 0;
525
526 AtaScsiAddress.AsULONG = 0;
527 while (TRUE)
528 {
529 DevExt = AtaFdoFindNextDeviceByPath(ChanExt, &AtaScsiAddress, TRUE, NULL);
530 if (!DevExt)
531 break;
532
533 if (DevExt->NotPresent)
534 {
535 if (AtaScsiAddress.Lun == 0)
536 {
537 AtaSetRegistryKey(ChanExt,
538 AtaScsiAddress.TargetId,
540 DEV_NONE);
541 }
542
543 DevExt->ReportedMissing = TRUE;
544 continue;
545 }
546
547 if (AtaScsiAddress.Lun == 0)
548 {
549 AtaSetRegistryKey(ChanExt, AtaScsiAddress.TargetId,
552
553 AtaSetRegistryKey(ChanExt,
554 AtaScsiAddress.TargetId,
557 }
558
559 DeviceRelations->Objects[DeviceRelations->Count++] = DevExt->Common.Self;
561 }
562}
#define DD_ATA_REG_XFER_MODE_SELECTED
Definition: ata_user.h:16
#define DD_ATA_REG_XFER_MODE_SUPPORTED
Definition: ata_user.h:15
VOID AtaSetRegistryKey(_In_ PATAPORT_CHANNEL_EXTENSION ChanExt, _In_ UCHAR TargetId, _In_ PCWSTR KeyName, _In_ ULONG KeyValue)
Definition: atapi.c:180
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
PDEVICE_OBJECT Self
Definition: atapi.h:432
ULONG TransferModeSelectedBitmap
Definition: atapi.h:527
ULONG TransferModeSupportedBitmap
Definition: atapi.h:518
ATAPORT_COMMON_EXTENSION Common
Definition: atapi.h:455
ULONG AsULONG
Definition: atapi.h:69
UCHAR TargetId
Definition: atapi.h:60
#define ObReferenceObject
Definition: obfuncs.h:204

Referenced by AtaFdoQueryBusRelations().

◆ AtaFdoQueryBusRelations()

NTSTATUS AtaFdoQueryBusRelations ( _In_ PATAPORT_CHANNEL_EXTENSION  ChanExt,
_In_ PIRP  Irp 
)

Definition at line 566 of file enum.c.

569{
570 PDEVICE_RELATIONS DeviceRelations = NULL;
571 ULONG Size, PdoCount;
572 ATA_SCSI_ADDRESS AtaScsiAddress;
573#if DBG
574 LARGE_INTEGER TimeStart, TimeFinish;
575 ULONG EnumTimeMs;
576#endif
577
578 PAGED_CODE();
579
580#if DBG
581 KeQuerySystemTime(&TimeStart);
582#endif
583
584 AtaScsiAddress.AsULONG = 0;
585 while (TRUE)
586 {
588
589 DevExt = AtaFdoFindNextDeviceByPath(ChanExt, &AtaScsiAddress, TRUE, NULL);
590 if (!DevExt)
591 break;
592
593 DevExt->NotPresent = TRUE;
594
595 if (DevExt->Device.AtaScsiAddress.Lun == 0)
596 {
597 AtaGetRegistryKey(ChanExt,
601 MAXULONG);
602 }
603 }
604
605 AtaFdoEnumeratePort(ChanExt);
606
607 PdoCount = 0;
608 AtaScsiAddress.AsULONG = 0;
609 while (TRUE)
610 {
612
613 DevExt = AtaFdoFindNextDeviceByPath(ChanExt, &AtaScsiAddress, TRUE, NULL);
614 if (!DevExt)
615 break;
616
617 if (!DevExt->NotPresent)
618 ++PdoCount;
619 }
620
621 Size = FIELD_OFFSET(DEVICE_RELATIONS, Objects[PdoCount]);
623 if (!DeviceRelations)
624 {
625 ERR("Failed to allocate device relations\n");
626 goto Cleanup;
627 }
628
629 AtaFdoInitializeDeviceRelations(ChanExt, DeviceRelations);
630
631#if DBG
632 KeQuerySystemTime(&TimeFinish);
633 EnumTimeMs = (TimeFinish.QuadPart - TimeStart.QuadPart) / 10000;
634 if (EnumTimeMs >= 5000)
635 {
636 WARN("%lu: QBR request took %lu ms, %lu devices\n",
637 ChanExt->ScsiPortNumber,
638 EnumTimeMs,
639 DeviceRelations->Count);
640 }
641 else
642 {
643 INFO("%lu: QBR request took %lu ms, %lu devices\n",
644 ChanExt->ScsiPortNumber,
645 EnumTimeMs,
646 DeviceRelations->Count);
647 }
648#endif
649
650 Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
651 return STATUS_SUCCESS;
652
653Cleanup:
654 if (DeviceRelations)
655 ExFreePoolWithTag(DeviceRelations, ATAPORT_TAG);
656
658}
#define ExAllocatePoolUninitialized
#define DD_ATA_REG_XFER_MODE_ALLOWED
Definition: ata_user.h:14
#define ATAPORT_TAG
Definition: atapi.h:171
#define WARN(fmt,...)
Definition: precomp.h:61
_In_ PIRP Irp
Definition: csq.h:116
static const WCHAR Cleanup[]
Definition: register.c:80
static VOID AtaFdoEnumeratePort(_In_ PATAPORT_CHANNEL_EXTENSION ChanExt)
Definition: enum.c:416
static VOID AtaFdoInitializeDeviceRelations(_In_ PATAPORT_CHANNEL_EXTENSION ChanExt, _In_ PDEVICE_RELATIONS DeviceRelations)
Definition: enum.c:515
#define ULONG_PTR
Definition: config.h:101
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define PagedPool
Definition: env_spec_w32.h:308
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define STATUS_SUCCESS
Definition: shellext.h:65
ULONG TransferModeUserAllowedMask
Definition: atapi.h:503
ATA_SCSI_ADDRESS AtaScsiAddress
Definition: atapi.h:100
#define MAXULONG
Definition: typedefs.h:251
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
LONGLONG QuadPart
Definition: typedefs.h:114
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539

Referenced by AtaFdoPnp().

◆ AtaFdoQueryDeviceCount()

static ULONG AtaFdoQueryDeviceCount ( _In_ PATAPORT_PORT_DATA  PortData)
static

Definition at line 378 of file enum.c.

380{
381 PAGED_CODE();
382
383 KeClearEvent(&PortData->Worker.EnumerationEvent);
385 KeWaitForSingleObject(&PortData->Worker.EnumerationEvent,
386 Executive,
388 FALSE,
389 NULL);
390 return PortData->Worker.DeviceCount;
391}
@ ACTION_ENUM_PORT
Definition: atapi.h:244
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
#define KernelMode
Definition: asm.h:38
@ Executive
Definition: ketypes.h:467

Referenced by AtaFdoEnumeratePort().

◆ AtaFdoQueryDeviceStatus()

static ATA_DEVICE_STATUS AtaFdoQueryDeviceStatus ( _In_ PATAPORT_PORT_DATA  PortData,
_In_ PATAPORT_DEVICE_EXTENSION  DevExt,
_In_ ATA_PORT_ACTION  Action 
)
static

Definition at line 396 of file enum.c.

400{
401 PAGED_CODE();
402
403 KeClearEvent(&DevExt->Worker.EnumerationEvent);
404 AtaDeviceQueueEvent(PortData, DevExt, Action);
405 KeWaitForSingleObject(&DevExt->Worker.EnumerationEvent,
406 Executive,
408 FALSE,
409 NULL);
410 return DevExt->Worker.EnumStatus;
411}
_In_ WDFIOTARGET _In_ _Strict_type_match_ WDF_IO_TARGET_SENT_IO_ACTION Action
Definition: wdfiotarget.h:510

Referenced by AtaFdoEnumeratePort().

◆ AtaPdoFillIdentificationStrings()

static VOID AtaPdoFillIdentificationStrings ( _In_ PATAPORT_DEVICE_EXTENSION  DevExt)
static

Definition at line 104 of file enum.c.

106{
107 PIDENTIFY_DEVICE_DATA IdentifyData = &DevExt->IdentifyDeviceData;
108 PCHAR End;
109 ULONG i;
111 size_t Remaining;
112
113 PAGED_CODE();
114
115 /*
116 * For ATAPI devices inquiry data is preferred over identify data.
117 * ATA strings are *not* byte-swapped for early ATAPI drives (NEC CDR-260, etc.).
118 */
119 if (IS_ATAPI(&DevExt->Device))
120 {
121 /* Combine VendorId and ProductId, separated by a space */
122 End = AtaCopyIdStringSafe(DevExt->FriendlyName,
123 DevExt->InquiryData.VendorId,
124 RTL_FIELD_SIZE(INQUIRYDATA, VendorId),
125 ' ');
126 End = AtaTrimIdString(DevExt->FriendlyName, End);
127 *End++ = ' ';
128 End = AtaCopyIdStringSafe(End,
129 DevExt->InquiryData.ProductId,
130 RTL_FIELD_SIZE(INQUIRYDATA, ProductId),
131 ' ');
132 AtaTrimIdString(DevExt->FriendlyName, End);
133
134 /* Copy ProductRevisionLevel */
135 End = AtaCopyIdStringSafe(DevExt->RevisionNumber,
136 DevExt->InquiryData.ProductRevisionLevel,
137 RTL_FIELD_SIZE(INQUIRYDATA, ProductRevisionLevel),
138 ' ');
139 AtaTrimIdString(DevExt->RevisionNumber, End);
140 }
141 else
142 {
143 /* Copy ModelNumber from a byte-swapped ATA string */
144 End = AtaCopyIdStringSafe(DevExt->FriendlyName,
145 IdentifyData->ModelNumber,
147 ' ');
148 AtaSwapIdString(DevExt->FriendlyName, ATAPORT_FN_FIELD / 2);
149 AtaTrimIdString(DevExt->FriendlyName, End);
150
151 /* Copy FirmwareRevision from a byte-swapped ATA string */
152 End = AtaCopyIdStringSafe(DevExt->RevisionNumber,
153 IdentifyData->FirmwareRevision,
155 ' ');
156 AtaSwapIdString(DevExt->RevisionNumber, ATAPORT_RN_FIELD / 2);
157 AtaTrimIdString(DevExt->RevisionNumber, End);
158 }
159
160 End = DevExt->SerialNumber;
161 Remaining = sizeof(DevExt->SerialNumber);
162
163 /* Format the serial number */
164 for (i = 0; i < sizeof(IdentifyData->SerialNumber); ++i)
165 {
167 Remaining,
168 &End,
169 &Remaining,
170 0,
171 "%2x",
172 IdentifyData->SerialNumber[i]);
174 }
175
176 INFO("FriendlyName: '%s'\n", DevExt->FriendlyName);
177 INFO("RevisionNumber: '%s'\n", DevExt->RevisionNumber);
178 INFO("SerialNumber: '%s'\n", DevExt->SerialNumber);
179}
#define ATAPORT_RN_FIELD
Definition: atapi.h:197
#define ATAPORT_FN_FIELD
The maximum length of identifier strings for ATA devices excluding the terminating NULL.
Definition: atapi.h:195
#define IS_ATAPI(Device)
Definition: atapi.h:176
LONG NTSTATUS
Definition: precomp.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
PCHAR AtaCopyIdStringSafe(_Out_writes_bytes_all_(MaxLength) PCHAR Destination, _In_reads_bytes_(MaxLength) PUCHAR Source, _In_ ULONG MaxLength, _In_ CHAR DefaultCharacter)
Definition: enum.c:35
VOID AtaSwapIdString(_Inout_updates_bytes_(WordCount *sizeof(USHORT)) PVOID Buffer, _In_range_(>, 0) ULONG WordCount)
Definition: enum.c:64
static PCHAR AtaTrimIdString(_In_ _Post_z_ PCHAR Start, _In_ PCHAR End)
Definition: enum.c:83
Status
Definition: gdiplustypes.h:25
#define RTL_FIELD_SIZE(type, field)
Definition: kdb_expr.c:86
NTSTRSAFEVAPI RtlStringCchPrintfExA(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cchDest, _Outptr_opt_result_buffer_(*pcchRemaining) NTSTRSAFE_PSTR *ppszDestEnd, _Out_opt_ size_t *pcchRemaining, _In_ STRSAFE_DWORD dwFlags, _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,...)
Definition: ntstrsafe.h:1218
UCHAR FirmwareRevision[8]
Definition: ata.h:25
UCHAR ModelNumber[40]
Definition: ata.h:26
UCHAR SerialNumber[20]
Definition: ata.h:22

Referenced by AtaPdoInit().

◆ AtaPdoInit()

static VOID AtaPdoInit ( _In_ PATAPORT_CHANNEL_EXTENSION  ChanExt,
_In_ PATAPORT_DEVICE_EXTENSION  DevExt 
)
static

Definition at line 311 of file enum.c.

314{
315 PAGED_CODE();
316
318
319 if (IS_ATAPI(&DevExt->Device))
320 {
321 if (AtaDeviceIsSuperFloppy(DevExt))
322 DevExt->Device.DeviceFlags |= DEVICE_IS_SUPER_FLOPPY;
323
324 if (AtaDevIsTape(&DevExt->IdentifyPacketData))
325 {
326 INFO("Tape drive detected '%s'\n", DevExt->FriendlyName);
327 }
328 }
329 else
330 {
331 if (ChanExt->PortData.PortFlags & PORT_FLAG_NCQ)
333
336 }
337
338 if (DevExt->Device.AtaScsiAddress.Lun == 0)
339 {
340 AtaSetRegistryKey(ChanExt,
341 DevExt->Device.AtaScsiAddress.TargetId,
343 DevExt->DeviceType);
344
345 AtaSetRegistryKey(ChanExt,
346 DevExt->Device.AtaScsiAddress.TargetId,
348 DevExt->InquiryData.DeviceType);
349
350 AtaGetRegistryKey(ChanExt,
351 DevExt->Device.AtaScsiAddress.TargetId,
353 &DevExt->TransferModeUserAllowedMask,
354 MAXULONG);
355 }
356
357 /* Will be unlocked upon PnP START IRP */
359
360 if (!AtaDevIsSsd(&DevExt->IdentifyDeviceData))
361 {
362 /* The spindle motor requires an inrush of power at start-up */
363 DevExt->Common.Self->Flags |= DO_POWER_INRUSH;
364 }
365 if (DevExt->InquiryData.RemovableMedia)
366 {
367 /* Distinguish between fixed and removable drives (e.g. CFA media) */
368 DevExt->Common.Self->Characteristics |= FILE_REMOVABLE_MEDIA;
369 }
370 DevExt->Common.Self->Flags &= ~DO_DEVICE_INITIALIZING;
371
372 DevExt->Device.DeviceFlags &= ~DEVICE_UNINITIALIZED;
373}
#define DD_ATA_REG_SCSI_DEVICE_TYPE
Definition: ata_user.h:12
#define PORT_FLAG_NCQ
Definition: atapi.h:339
#define DEVICE_IS_SUPER_FLOPPY
Definition: atapi.h:89
#define QUEUE_FLAG_FROZEN_PNP
Definition: atapi.h:107
DECLSPEC_NOINLINE_FROM_PAGED VOID AtaReqFreezeQueue(_In_ PATAPORT_DEVICE_EXTENSION DevExt, _In_ ULONG ReasonFlags)
Definition: scsi.c:1351
VOID AtaCreateStandardInquiryData(_In_ PATAPORT_DEVICE_EXTENSION DevExt)
Definition: satl.c:1166
VOID AtaDeviceSetAddressingMode(_In_ PATAPORT_DEVICE_EXTENSION DevExt)
Definition: enum.c:182
static VOID AtaDeviceEnableQueuedCommands(_In_ PATAPORT_DEVICE_EXTENSION DevExt)
Definition: enum.c:267
static VOID AtaPdoFillIdentificationStrings(_In_ PATAPORT_DEVICE_EXTENSION DevExt)
Definition: enum.c:104
static BOOLEAN AtaDeviceIsSuperFloppy(_In_ PATAPORT_DEVICE_EXTENSION DevExt)
Definition: enum.c:293
FORCEINLINE BOOLEAN AtaDevIsSsd(_In_ PIDENTIFY_DEVICE_DATA IdentifyData)
FORCEINLINE BOOLEAN AtaDevIsTape(_In_ PIDENTIFY_PACKET_DATA IdentifyPacketData)
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
#define DO_POWER_INRUSH

Referenced by AtaFdoEnumeratePort().

◆ AtaSwapIdString()

VOID AtaSwapIdString ( _Inout_updates_bytes_(WordCount *sizeof(USHORT)) PVOID  Buffer,
_In_range_(>, 0) ULONG  WordCount 
)

Definition at line 64 of file enum.c.

67{
68 PUSHORT Word = Buffer;
69
70 /* The buffer should be USHORT aligned for ARM compatibility */
71 ASSERT(((ULONG_PTR)Buffer & 1) == 0);
72
73 while (WordCount--)
74 {
75 *Word = RtlUshortByteSwap(*Word);
76 ++Word;
77 }
78}
Definition: bufpool.h:45
uint16_t * PUSHORT
Definition: typedefs.h:56
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define RtlUshortByteSwap(_x)
Definition: rtlfuncs.h:3214

Referenced by AtaCreateAtapiStandardInquiryData(), and AtaPdoFillIdentificationStrings().

◆ AtaTrimIdString()

static PCHAR AtaTrimIdString ( _In_ _Post_z_ PCHAR  Start,
_In_ PCHAR  End 
)
static

Definition at line 83 of file enum.c.

86{
87 PCHAR Current = End - 1;
88
89 PAGED_CODE();
90
91 /* Remove trailing spaces */
92 while (Current >= Start && *Current == ' ')
93 {
94 --Current;
95 }
96 Current[1] = ANSI_NULL;
97
98 return (Current + 1);
99}
return pTarget Start()
#define ANSI_NULL

Referenced by AtaPdoFillIdentificationStrings().