https://git.reactos.org/?p=reactos.git;a=commitdiff;h=0ed5db45a4784ecb10252064dd42e494729ded67

commit 0ed5db45a4784ecb10252064dd42e494729ded67
Author:     Stanislav Motylkov <[email protected]>
AuthorDate: Mon Dec 28 01:38:06 2020 +0300
Commit:     Stanislav Motylkov <[email protected]>
CommitDate: Thu Dec 31 15:54:42 2020 +0300

    [UNIATA] Emulate SCSI INQUIRY to properly recognize Xbox DVD drives
    
    CORE-16692
---
 drivers/storage/ide/uniata/id_ata.cpp | 76 +++++++++++++++++++++++++++++++++++
 1 file changed, 76 insertions(+)

diff --git a/drivers/storage/ide/uniata/id_ata.cpp 
b/drivers/storage/ide/uniata/id_ata.cpp
index 0a0c586a7ce..a49811ba90d 100644
--- a/drivers/storage/ide/uniata/id_ata.cpp
+++ b/drivers/storage/ide/uniata/id_ata.cpp
@@ -9499,6 +9499,82 @@ reject_srb:
                    (Srb->Cdb[0] != SCSIOP_ATA_PASSTHROUGH)/* &&
                    (Srb->Cdb[0] != SCSIOP_REPORT_LUNS)*/) {
                     KdPrint3((PRINT_PREFIX "Try ATAPI send %x\n", 
Srb->Cdb[0]));
+#ifdef __REACTOS__
+                    status = SRB_STATUS_BUSY;
+
+                    if (Srb->Cdb[0] == SCSIOP_INQUIRY &&
+                        (LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) &&
+                        (LunExt->IdentifyData.DeviceType == ATAPI_TYPE_CDROM ||
+                        LunExt->IdentifyData.DeviceType == ATAPI_TYPE_OPTICAL) 
&&
+                        LunExt->IdentifyData.ModelNumber[0])
+                    {
+                        ULONG j;
+                        CCHAR vendorId[26];
+
+                        // Attempt to identify known broken CD/DVD drives
+                        for (j = 0; j < sizeof(vendorId); j += 2)
+                        {
+                            // Build a buffer based on the identify data.
+                            MOV_DW_SWP(vendorId[j], 
((PUCHAR)LunExt->IdentifyData.ModelNumber)[j]);
+                        }
+
+                        // Emulate INQUIRY support for broken CD/DVD drives 
(e.g. Microsoft Xbox).
+                        // Currently we implement it by explicitly checking 
the drive name from ATA IDENTIFY PACKET.
+                        if (!AtapiStringCmp(vendorId, "THOMSON-DVD", 11) ||
+                            !AtapiStringCmp(vendorId, "PHILIPS XBOX DVD 
DRIVE", 22) ||
+                            !AtapiStringCmp(vendorId, "PHILIPS J5 3235C", 16) 
||
+                            !AtapiStringCmp(vendorId, "SAMSUNG DVD-ROM 
SDG-605B", 24))
+                        {
+                            // TODO:
+                            // Better send INQUIRY and then check for 
chan->ReturningMediaStatus >> 4 == SCSI_SENSE_ILLEGAL_REQUEST
+                            // in AtapiInterrupt__() and emulate the response 
only in this case.
+
+                            // If this hack stays for long enough, consider 
adding Xbox 360 drive names to the condition,
+                            // as they are affected by the same problem.
+
+                            // See https://jira.reactos.org/browse/CORE-16692
+                            ULONG i;
+                            PINQUIRYDATA inquiryData = 
(PINQUIRYDATA)(Srb->DataBuffer);
+                            PIDENTIFY_DATA2 identifyData = 
&(LunExt->IdentifyData);
+
+                            // Zero INQUIRY data structure.
+                            RtlZeroMemory((PCHAR)(Srb->DataBuffer), 
Srb->DataTransferLength);
+
+                            // This is ATAPI CD- or DVD-ROM.
+                            inquiryData->DeviceType = 
READ_ONLY_DIRECT_ACCESS_DEVICE;
+
+                            // Set the removable bit, if applicable.
+                            if (LunExt->DeviceFlags & DFLAGS_REMOVABLE_DRIVE) {
+                                KdPrint2((PRINT_PREFIX 
+                                          "RemovableMedia\n"));
+                                inquiryData->RemovableMedia = 1;
+                            }
+                            // Set the Relative Addressing (LBA) bit, if 
applicable.
+                            if (LunExt->DeviceFlags & DFLAGS_LBA_ENABLED) {
+                                inquiryData->RelativeAddressing = 1;
+                                KdPrint2((PRINT_PREFIX 
+                                          "RelativeAddressing\n"));
+                            }
+                            // Set the CommandQueue bit
+                            inquiryData->CommandQueue = 1;
+
+                            // Fill in vendor identification fields.
+                            for (i = 0; i < 24; i += 2) {
+                                
MOV_DW_SWP(inquiryData->DeviceIdentificationString[i], 
((PUCHAR)identifyData->ModelNumber)[i]);
+                            }
+
+                            // Move firmware revision from IDENTIFY data to
+                            // product revision in INQUIRY data.
+                            for (i = 0; i < 4; i += 2) {
+                                
MOV_DW_SWP(inquiryData->ProductRevisionLevel[i], 
((PUCHAR)identifyData->FirmwareRevision)[i]);
+                            }
+
+                            status = SRB_STATUS_SUCCESS;
+                        }
+                    }
+
+                    if (status != SRB_STATUS_SUCCESS)
+#endif
                     status = AtapiSendCommand(HwDeviceExtension, Srb, 
CMD_ACTION_ALL);
                 } else {
                     KdPrint2((PRINT_PREFIX "Try IDE send\n"));

Reply via email to