diff --git a/drivers/storage/storahci/storahci.c b/drivers/storage/storahci/storahci.c index 88d5feb1c66..97138a6a0a4 100644 --- a/drivers/storage/storahci/storahci.c +++ b/drivers/storage/storahci/storahci.c @@ -401,7 +401,6 @@ AhciStartPort ( AhciDebugPrint("\tDET == %x Unsupported\n", ssts.DET); return FALSE; } - }// -- AhciStartPort(); /** @@ -1242,12 +1241,34 @@ AhciATAPI_CFIS ( __in PAHCI_SRB_EXTENSION SrbExtension ) { + PAHCI_COMMAND_TABLE cmdTable; UNREFERENCED_PARAMETER(PortExtension); - UNREFERENCED_PARAMETER(SrbExtension); AhciDebugPrint("AhciATAPI_CFIS()\n"); - return 2; + cmdTable = (PAHCI_COMMAND_TABLE)SrbExtension; + + NT_ASSERT(SrbExtension->CommandReg == IDE_COMMAND_ATAPI_PACKET); + + AhciZeroMemory((PCHAR)cmdTable->CFIS, sizeof(cmdTable->CFIS)); + + cmdTable->CFIS[AHCI_ATA_CFIS_FisType] = FIS_TYPE_REG_H2D; // FIS Type + cmdTable->CFIS[AHCI_ATA_CFIS_PMPort_C] = (1 << 7); // PM Port & C + cmdTable->CFIS[AHCI_ATA_CFIS_CommandReg] = SrbExtension->CommandReg; + + cmdTable->CFIS[AHCI_ATA_CFIS_FeaturesLow] = SrbExtension->FeaturesLow; + cmdTable->CFIS[AHCI_ATA_CFIS_LBA0] = SrbExtension->LBA0; + cmdTable->CFIS[AHCI_ATA_CFIS_LBA1] = SrbExtension->LBA1; + cmdTable->CFIS[AHCI_ATA_CFIS_LBA2] = SrbExtension->LBA2; + cmdTable->CFIS[AHCI_ATA_CFIS_Device] = SrbExtension->Device; + cmdTable->CFIS[AHCI_ATA_CFIS_LBA3] = SrbExtension->LBA3; + cmdTable->CFIS[AHCI_ATA_CFIS_LBA4] = SrbExtension->LBA4; + cmdTable->CFIS[AHCI_ATA_CFIS_LBA5] = SrbExtension->LBA5; + cmdTable->CFIS[AHCI_ATA_CFIS_FeaturesHigh] = SrbExtension->FeaturesHigh; + cmdTable->CFIS[AHCI_ATA_CFIS_SectorCountLow] = SrbExtension->SectorCountLow; + cmdTable->CFIS[AHCI_ATA_CFIS_SectorCountHigh] = SrbExtension->SectorCountHigh; + + return 5; }// -- AhciATAPI_CFIS(); /** @@ -1565,9 +1586,47 @@ AhciProcessIO ( return; }// -- AhciProcessIO(); +/** + * @name AtapiInquiryCompletion + * @implemented + * + * AtapiInquiryCompletion routine should be called after device signals + * for device inquiry request is completed (through interrupt) -- ATAPI Device only + * + * @param PortExtension + * @param Srb + * + */ +VOID +AtapiInquiryCompletion ( + __in PAHCI_PORT_EXTENSION PortExtension, + __in PSCSI_REQUEST_BLOCK Srb + ) +{ + BOOLEAN status; + PAHCI_ADAPTER_EXTENSION AdapterExtension; + + AhciDebugPrint("AtapiInquiryCompletion()\n"); + + NT_ASSERT(Srb != NULL); + NT_ASSERT(PortExtension != NULL); + + AdapterExtension = PortExtension->AdapterExtension; + + // send queue depth + status = StorPortSetDeviceQueueDepth(PortExtension->AdapterExtension, + Srb->PathId, + Srb->TargetId, + Srb->Lun, + AHCI_Global_Port_CAP_NCS(AdapterExtension->CAP)); + + NT_ASSERT(status == TRUE); + return; +}// -- AtapiInquiryCompletion(); + /** * @name InquiryCompletion - * @not_implemented + * @implemented * * InquiryCompletion routine should be called after device signals * for device inquiry request is completed (through interrupt) @@ -1719,6 +1778,96 @@ InquiryCompletion ( return; }// -- InquiryCompletion(); + /** + * @name AhciATAPICommand + * @implemented + * + * Handles ATAPI Requests commands + * + * @param AdapterExtension + * @param Srb + * @param Cdb + * + * @return + * return STOR status for AhciATAPICommand + */ +UCHAR +AhciATAPICommand ( + __in PAHCI_ADAPTER_EXTENSION AdapterExtension, + __in PSCSI_REQUEST_BLOCK Srb, + __in PCDB Cdb + ) +{ + ULONG SrbFlags, DataBufferLength; + PAHCI_SRB_EXTENSION SrbExtension; + PAHCI_PORT_EXTENSION PortExtension; + + AhciDebugPrint("AhciATAPICommand()\n"); + + SrbFlags = Srb->SrbFlags; + SrbExtension = GetSrbExtension(Srb); + DataBufferLength = Srb->DataTransferLength; + PortExtension = &AdapterExtension->PortExtension[Srb->PathId]; + + NT_ASSERT(PortExtension->DeviceParams.DeviceType == AHCI_DEVICE_TYPE_ATAPI); + + NT_ASSERT(SrbExtension != NULL); + + SrbExtension->AtaFunction = ATA_FUNCTION_ATAPI_COMMAND; + SrbExtension->Flags = 0; + + if (SrbFlags & SRB_FLAGS_DATA_IN) + { + SrbExtension->Flags |= ATA_FLAGS_DATA_IN; + } + + if (SrbFlags & SRB_FLAGS_DATA_OUT) + { + SrbExtension->Flags |= ATA_FLAGS_DATA_OUT; + } + + SrbExtension->FeaturesLow = 0; + + SrbExtension->CompletionRoutine = NULL; + + NT_ASSERT(Cdb != NULL); + switch(Cdb->CDB10.OperationCode) + { + case SCSIOP_INQUIRY: + SrbExtension->Flags |= ATA_FLAGS_DATA_IN; + SrbExtension->CompletionRoutine = AtapiInquiryCompletion; + break; + case SCSIOP_READ: + SrbExtension->Flags |= ATA_FLAGS_USE_DMA; + SrbExtension->FeaturesLow = 0x5; + break; + case SCSIOP_WRITE: + SrbExtension->Flags |= ATA_FLAGS_USE_DMA; + SrbExtension->FeaturesLow = 0x1; + break; + } + + SrbExtension->CommandReg = IDE_COMMAND_ATAPI_PACKET; + + SrbExtension->LBA0 = 0; + SrbExtension->LBA1 = (UCHAR)(DataBufferLength >> 0); + SrbExtension->LBA2 = (UCHAR)(DataBufferLength >> 8); + SrbExtension->Device = 0; + SrbExtension->LBA3 = 0; + SrbExtension->LBA4 = 0; + SrbExtension->LBA5 = 0; + SrbExtension->FeaturesHigh = 0; + SrbExtension->SectorCountLow = 0; + SrbExtension->SectorCountHigh = 0; + + if ((SrbExtension->Flags & ATA_FLAGS_DATA_IN) || (SrbExtension->Flags & ATA_FLAGS_DATA_OUT)) + { + SrbExtension->pSgl = (PLOCAL_SCATTER_GATHER_LIST)StorPortGetScatterGatherList(AdapterExtension, Srb); + } + + return SRB_STATUS_PENDING; +}// -- AhciATAPICommand(); + /** * @name DeviceRequestSense * @implemented @@ -1732,21 +1881,28 @@ InquiryCompletion ( * @return * return STOR status for DeviceRequestSense */ -UCHAR DeviceRequestSense ( +UCHAR +DeviceRequestSense ( __in PAHCI_ADAPTER_EXTENSION AdapterExtension, __in PSCSI_REQUEST_BLOCK Srb, __in PCDB Cdb ) { PMODE_PARAMETER_HEADER ModeHeader; + PAHCI_PORT_EXTENSION PortExtension; AhciDebugPrint("DeviceRequestSense()\n"); - UNREFERENCED_PARAMETER(AdapterExtension); - NT_ASSERT(IsPortValid(AdapterExtension, Srb->PathId)); NT_ASSERT(Cdb->CDB10.OperationCode == SCSIOP_MODE_SENSE); + PortExtension = &AdapterExtension->PortExtension[Srb->PathId]; + + if (PortExtension->DeviceParams.DeviceType == AHCI_DEVICE_TYPE_ATAPI) + { + return AhciATAPICommand(AdapterExtension, Srb, Cdb); + } + ModeHeader = (PMODE_PARAMETER_HEADER)Srb->DataBuffer; NT_ASSERT(ModeHeader != NULL); @@ -1778,9 +1934,10 @@ UCHAR DeviceRequestSense ( * @param Cdb * * @return - * return STOR status for DeviceReportLuns + * return STOR status for DeviceRequestReadWrite */ -UCHAR DeviceRequestReadWrite ( +UCHAR +DeviceRequestReadWrite ( __in PAHCI_ADAPTER_EXTENSION AdapterExtension, __in PSCSI_REQUEST_BLOCK Srb, __in PCDB Cdb @@ -1800,6 +1957,11 @@ UCHAR DeviceRequestReadWrite ( SrbExtension = GetSrbExtension(Srb); PortExtension = &AdapterExtension->PortExtension[Srb->PathId]; + if (PortExtension->DeviceParams.DeviceType == AHCI_DEVICE_TYPE_ATAPI) + { + return AhciATAPICommand(AdapterExtension, Srb, Cdb); + } + DataTransferLength = Srb->DataTransferLength; BytesPerSector = PortExtension->DeviceParams.BytesPerLogicalSector; @@ -1882,9 +2044,10 @@ UCHAR DeviceRequestReadWrite ( * @param Cdb * * @return - * return STOR status for DeviceReportLuns + * return STOR status for DeviceRequestCapacity */ -UCHAR DeviceRequestCapacity ( +UCHAR +DeviceRequestCapacity ( __in PAHCI_ADAPTER_EXTENSION AdapterExtension, __in PSCSI_REQUEST_BLOCK Srb, __in PCDB Cdb @@ -1902,8 +2065,14 @@ UCHAR DeviceRequestCapacity ( NT_ASSERT(Srb->DataBuffer != NULL); NT_ASSERT(IsPortValid(AdapterExtension, Srb->PathId)); + PortExtension = &AdapterExtension->PortExtension[Srb->PathId]; + if (PortExtension->DeviceParams.DeviceType == AHCI_DEVICE_TYPE_ATAPI) + { + return AhciATAPICommand(AdapterExtension, Srb, Cdb); + } + if (Cdb->CDB10.OperationCode == SCSIOP_READ_CAPACITY) { ReadCapacity = (PREAD_CAPACITY_DATA)Srb->DataBuffer; @@ -1945,7 +2114,8 @@ UCHAR DeviceRequestCapacity ( * @return * return STOR status for DeviceRequestComplete */ -UCHAR DeviceRequestComplete ( +UCHAR +DeviceRequestComplete ( __in PAHCI_ADAPTER_EXTENSION AdapterExtension, __in PSCSI_REQUEST_BLOCK Srb, __in PCDB Cdb @@ -1974,22 +2144,30 @@ UCHAR DeviceRequestComplete ( * @return * return STOR status for DeviceReportLuns */ -UCHAR DeviceReportLuns ( +UCHAR +DeviceReportLuns ( __in PAHCI_ADAPTER_EXTENSION AdapterExtension, __in PSCSI_REQUEST_BLOCK Srb, __in PCDB Cdb ) { PLUN_LIST LunList; + PAHCI_PORT_EXTENSION PortExtension; AhciDebugPrint("DeviceReportLuns()\n"); - UNREFERENCED_PARAMETER(AdapterExtension); UNREFERENCED_PARAMETER(Cdb); + PortExtension = &AdapterExtension->PortExtension[Srb->PathId]; + NT_ASSERT(Srb->DataTransferLength >= sizeof(LUN_LIST)); NT_ASSERT(Cdb->CDB10.OperationCode == SCSIOP_REPORT_LUNS); + if (PortExtension->DeviceParams.DeviceType == AHCI_DEVICE_TYPE_ATAPI) + { + return AhciATAPICommand(AdapterExtension, Srb, Cdb); + } + LunList = (PLUN_LIST)Srb->DataBuffer; NT_ASSERT(LunList != NULL); @@ -2041,6 +2219,11 @@ DeviceInquiryRequest ( SrbExtension = GetSrbExtension(Srb); PortExtension = &AdapterExtension->PortExtension[Srb->PathId]; + if (PortExtension->DeviceParams.DeviceType == AHCI_DEVICE_TYPE_ATAPI) + { + return AhciATAPICommand(AdapterExtension, Srb, Cdb); + } + if (Srb->Lun != 0) { return SRB_STATUS_SELECTION_TIMEOUT;