X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=IntelFrameworkModulePkg%2FBus%2FPci%2FIdeBusDxe%2FAtapi.c;h=13375f0fbc6f845950b32032d61f0585f20040cc;hb=1910fbaf7014fab2012f06ab03829f0146cf32d4;hp=e7ddcb980ef1633951ffb79554ea6610520823e2;hpb=819d1488930d30b30bb467fcb3bf0f05b28d675e;p=mirror_edk2.git diff --git a/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/Atapi.c b/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/Atapi.c index e7ddcb980e..13375f0fbc 100644 --- a/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/Atapi.c +++ b/IntelFrameworkModulePkg/Bus/Pci/IdeBusDxe/Atapi.c @@ -1,4 +1,6 @@ /** @file + This file contains all helper functions on the ATAPI command + Copyright (c) 2006 - 2008, Intel Corporation All rights reserved. This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License @@ -17,28 +19,18 @@ in the LS-120 drive or ZIP drive. The media status is returned in the Error Status. - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @retval EFI_SUCCESS - The media status is achieved successfully and the media - can be read/written. - - @retval EFI_DEVICE_ERROR - Get Media Status Command is failed. - - @retval EFI_NO_MEDIA - There is no media in the drive. - - @retval EFI_WRITE_PROTECTED - The media is writing protected. + @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. - @note - This function must be called after the LS120EnableMediaStatus() - with second parameter set to TRUE - (means enable media status notification) is called. + @retval EFI_SUCCESS The media status is achieved successfully and the media + can be read/written. + @retval EFI_DEVICE_ERROR Get Media Status Command is failed. + @retval EFI_NO_MEDIA There is no media in the drive. + @retval EFI_WRITE_PROTECTED The media is writing protected. + @note This function must be called after the LS120EnableMediaStatus() + with second parameter set to TRUE + (means enable media status notification) is called. **/ EFI_STATUS LS120GetMediaStatus ( @@ -90,35 +82,27 @@ LS120GetMediaStatus ( // StatusValue = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error); - if (StatusValue & BIT1) { + if ((StatusValue & BIT1) != 0) { return EFI_NO_MEDIA; } - if (StatusValue & BIT6) { + if ((StatusValue & BIT6) != 0) { return EFI_WRITE_PROTECTED; } else { return EFI_SUCCESS; } } - /** This function is used to send Enable Media Status Notification Command or Disable Media Status Notification Command. - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @param[in] Enable - a flag that indicates whether enable or disable media - status notification. - - @retval EFI_SUCCESS - If command completes successfully. - - @retval EFI_DEVICE_ERROR - If command failed. + @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + @param Enable a flag that indicates whether enable or disable media + status notification. + @retval EFI_SUCCESS If command completes successfully. + @retval EFI_DEVICE_ERROR If command failed. **/ EFI_STATUS LS120EnableMediaStatus ( @@ -179,301 +163,202 @@ LS120EnableMediaStatus ( return EFI_SUCCESS; } - /** - This function is called by DiscoverIdeDevice() during its device - identification. - - Its main purpose is to get enough information for the device media - to fill in the Media data structure of the Block I/O Protocol interface. - - There are 5 steps to reach such objective: - - 1. Sends out the ATAPI Identify Command to the specified device. - Only ATAPI device responses to this command. If the command succeeds, - it returns the Identify data structure which filled with information - about the device. Since the ATAPI device contains removable media, - the only meaningful information is the device module name. - - 2. Sends out ATAPI Inquiry Packet Command to the specified device. - This command will return inquiry data of the device, which contains - the device type information. + This function reads the pending data in the device. - 3. Allocate sense data space for future use. We don't detect the media - presence here to improvement boot performance, especially when CD - media is present. The media detection will be performed just before - each BLK_IO read/write + @param IdeDev Indicates the calling context. - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. + @retval EFI_SUCCESS Successfully read. + @retval EFI_NOT_READY The BSY is set avoiding reading. - @retval EFI_SUCCESS - Identify ATAPI device successfully. - - @retval EFI_DEVICE_ERROR - ATAPI Identify Device Command failed or device type - is not supported by this IDE driver. +**/ +EFI_STATUS +AtapiReadPendingData ( + IN IDE_BLK_IO_DEV *IdeDev + ) +{ + UINT8 AltRegister; + UINT16 TempWordBuffer; - @note - Parameter "IdeDev" will be updated in this function. + AltRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.AltStatus); + if ((AltRegister & ATA_STSREG_BSY) == ATA_STSREG_BSY) { + return EFI_NOT_READY; + } + if ((AltRegister & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) { + TempWordBuffer = IDEReadPortB (IdeDev->PciIo,IdeDev->IoPort->Alt.AltStatus); + while ((TempWordBuffer & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) { + IDEReadPortWMultiple ( + IdeDev->PciIo, + IdeDev->IoPort->Data, + 1, + &TempWordBuffer + ); + TempWordBuffer = IDEReadPortB (IdeDev->PciIo,IdeDev->IoPort->Alt.AltStatus); + } + } + return EFI_SUCCESS; +} - TODO: EFI_OUT_OF_RESOURCES - add return value to function comment - TODO: EFI_OUT_OF_RESOURCES - add return value to function comment +/** + This function is called by either AtapiPacketCommandIn() or AtapiPacketCommandOut(). + It is used to transfer data between host and device. The data direction is specified + by the fourth parameter. + + @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used to record + all the information of the IDE device. + @param Buffer buffer contained data transferred between host and device. + @param ByteCount data size in byte unit of the buffer. + @param Read flag used to determine the data transfer direction. + Read equals 1, means data transferred from device to host; + Read equals 0, means data transferred from host to device. + @param TimeOut timeout value for wait DRQ ready before each data stream's transfer. + + @retval EFI_SUCCESS data is transferred successfully. + @retval EFI_DEVICE_ERROR the device failed to transfer data. **/ EFI_STATUS -ATAPIIdentify ( - IN IDE_BLK_IO_DEV *IdeDev +PioReadWriteData ( + IN IDE_BLK_IO_DEV *IdeDev, + IN UINT16 *Buffer, + IN UINT32 ByteCount, + IN BOOLEAN Read, + IN UINTN TimeOut ) { - EFI_IDENTIFY_DATA *AtapiIdentifyPointer; - UINT8 DeviceSelect; - EFI_STATUS Status; - // - // device select bit + // required transfer data in word unit. // - DeviceSelect = (UINT8) ((IdeDev->Device) << 4); + UINT32 RequiredWordCount; - AtapiIdentifyPointer = AllocatePool (sizeof (EFI_IDENTIFY_DATA)); - if (AtapiIdentifyPointer == NULL) { - return EFI_OUT_OF_RESOURCES; - } // - // Send ATAPI Identify Command to get IDENTIFY data. + // actual transfer data in word unit. // - Status = AtaPioDataIn ( - IdeDev, - (VOID *) AtapiIdentifyPointer, - sizeof (EFI_IDENTIFY_DATA), - ATA_CMD_IDENTIFY_DEVICE, - DeviceSelect, - 0, - 0, - 0, - 0 - ); - - if (EFI_ERROR (Status)) { - gBS->FreePool (AtapiIdentifyPointer); - return EFI_DEVICE_ERROR; - } - - IdeDev->pIdData = AtapiIdentifyPointer; - PrintAtaModuleName (IdeDev); + UINT32 ActualWordCount; + UINT32 WordCount; + EFI_STATUS Status; + UINT16 *PtrBuffer; // - // Send ATAPI Inquiry Packet Command to get INQUIRY data. + // No data transfer is premitted. // - Status = AtapiInquiry (IdeDev); - if (EFI_ERROR (Status)) { - gBS->FreePool (IdeDev->pIdData); - // - // Make sure the pIdData will not be freed again. - // - IdeDev->pIdData = NULL; - return EFI_DEVICE_ERROR; + if (ByteCount == 0) { + return EFI_SUCCESS; } // - // Get media removable info from INQUIRY data. - // - IdeDev->BlkIo.Media->RemovableMedia = (UINT8) ((IdeDev->pInquiryData->RMB & 0x80) == 0x80); - - // - // Identify device type via INQUIRY data. - // - switch (IdeDev->pInquiryData->peripheral_type & 0x1f) { - + // for performance, we assert the ByteCount is an even number + // which is actually a resonable assumption + ASSERT((ByteCount%2) == 0); + + PtrBuffer = Buffer; + RequiredWordCount = ByteCount / 2; // - // Magnetic Disk + // ActuralWordCount means the word count of data really transferred. // - case 0x00: + ActualWordCount = 0; + while (ActualWordCount < RequiredWordCount) { + // - // device is LS120 or ZIP drive. + // before each data transfer stream, the host should poll DRQ bit ready, + // to see whether indicates device is ready to transfer data. // - IdeDev->Type = IdeMagnetic; - - IdeDev->BlkIo.Media->MediaId = 0; + Status = DRQReady2 (IdeDev, TimeOut); + if (EFI_ERROR (Status)) { + return CheckErrorStatus (IdeDev); + } + // - // Give initial value + // read Status Register will clear interrupt // - IdeDev->BlkIo.Media->MediaPresent = FALSE; - - IdeDev->BlkIo.Media->LastBlock = 0; - IdeDev->BlkIo.Media->BlockSize = 0x200; - break; - - // - // CD-ROM - // - case 0x05: + IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status); - IdeDev->Type = IdeCdRom; - IdeDev->BlkIo.Media->MediaId = 0; // - // Give initial value + // get current data transfer size from Cylinder Registers. // - IdeDev->BlkIo.Media->MediaPresent = FALSE; + WordCount = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb) << 8; + WordCount = WordCount | IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb); + WordCount = WordCount & 0xffff; + WordCount /= 2; - IdeDev->BlkIo.Media->LastBlock = 0; - IdeDev->BlkIo.Media->BlockSize = 0x800; - IdeDev->BlkIo.Media->ReadOnly = TRUE; - break; + WordCount = MIN (WordCount, (RequiredWordCount - ActualWordCount)); - // - // Tape - // - case 0x01: + if (Read) { + IDEReadPortWMultiple ( + IdeDev->PciIo, + IdeDev->IoPort->Data, + WordCount, + PtrBuffer + ); + } else { + IDEWritePortWMultiple ( + IdeDev->PciIo, + IdeDev->IoPort->Data, + WordCount, + PtrBuffer + ); + } - // - // WORM - // - case 0x04: + PtrBuffer += WordCount; + ActualWordCount += WordCount; + } - // - // Optical - // - case 0x07: - - default: - IdeDev->Type = IdeUnknown; - gBS->FreePool (IdeDev->pIdData); - gBS->FreePool (IdeDev->pInquiryData); + if (Read) { // - // Make sure the pIdData and pInquiryData will not be freed again. + // In the case where the drive wants to send more data than we need to read, + // the DRQ bit will be set and cause delays from DRQClear2(). + // We need to read data from the drive until it clears DRQ so we can move on. // - IdeDev->pIdData = NULL; - IdeDev->pInquiryData = NULL; - return EFI_DEVICE_ERROR; + AtapiReadPendingData (IdeDev); } // - // original sense data numbers + // After data transfer is completed, normally, DRQ bit should clear. // - IdeDev->SenseDataNumber = 20; - - IdeDev->SenseData = AllocatePool (IdeDev->SenseDataNumber * sizeof (ATAPI_REQUEST_SENSE_DATA)); - if (IdeDev->SenseData == NULL) { - gBS->FreePool (IdeDev->pIdData); - gBS->FreePool (IdeDev->pInquiryData); - // - // Make sure the pIdData and pInquiryData will not be freed again. - // - IdeDev->pIdData = NULL; - IdeDev->pInquiryData = NULL; - return EFI_OUT_OF_RESOURCES; + Status = DRQClear2 (IdeDev, ATAPITIMEOUT); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; } - return EFI_SUCCESS; + // + // read status register to check whether error happens. + // + return CheckErrorStatus (IdeDev); } /** - Sends out ATAPI Inquiry Packet Command to the specified device. - This command will return INQUIRY data of the device. - - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @retval EFI_SUCCESS - Inquiry command completes successfully. - - @retval EFI_DEVICE_ERROR - Inquiry command failed. - - @note - Parameter "IdeDev" will be updated in this function. + This function is used to send out ATAPI commands conforms to the Packet Command + with PIO Data In Protocol. + + @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + @param Packet pointer pointing to ATAPI_PACKET_COMMAND data structure + which contains the contents of the command. + @param Buffer buffer contained data transferred from device to host. + @param ByteCount data size in byte unit of the buffer. + @param TimeOut this parameter is used to specify the timeout value for the + PioReadWriteData() function. + + @retval EFI_SUCCESS send out the ATAPI packet command successfully + and device sends data successfully. + @retval EFI_DEVICE_ERROR the device failed to send data. **/ EFI_STATUS -AtapiInquiry ( - IN IDE_BLK_IO_DEV *IdeDev +AtapiPacketCommandIn ( + IN IDE_BLK_IO_DEV *IdeDev, + IN ATAPI_PACKET_COMMAND *Packet, + IN UINT16 *Buffer, + IN UINT32 ByteCount, + IN UINTN TimeOut ) { - ATAPI_PACKET_COMMAND Packet; - EFI_STATUS Status; - ATAPI_INQUIRY_DATA *InquiryData; + UINT16 *CommandIndex; + EFI_STATUS Status; + UINT32 Count; // - // prepare command packet for the ATAPI Inquiry Packet Command. - // - ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND)); - Packet.Inquiry.opcode = ATA_CMD_INQUIRY; - Packet.Inquiry.page_code = 0; - Packet.Inquiry.allocation_length = sizeof (ATAPI_INQUIRY_DATA); - - InquiryData = AllocatePool (sizeof (ATAPI_INQUIRY_DATA)); - if (InquiryData == NULL) { - return EFI_DEVICE_ERROR; - } - - // - // Send command packet and get requested Inquiry data. - // - Status = AtapiPacketCommandIn ( - IdeDev, - &Packet, - (UINT16 *) InquiryData, - sizeof (ATAPI_INQUIRY_DATA), - ATAPITIMEOUT - ); - if (EFI_ERROR (Status)) { - gBS->FreePool (InquiryData); - return EFI_DEVICE_ERROR; - } - - IdeDev->pInquiryData = InquiryData; - - return EFI_SUCCESS; -} - -/** - This function is used to send out ATAPI commands conforms to the - Packet Command with PIO Data In Protocol. - - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @param[in] *Packet - pointer pointing to ATAPI_PACKET_COMMAND data structure - which contains the contents of the command. - - @param[in] *Buffer - buffer contained data transferred from device to host. - - @param[in] ByteCount - data size in byte unit of the buffer. - - @param[in] TimeOut - this parameter is used to specify the timeout - value for the PioReadWriteData() function. - - @retval EFI_SUCCESS - send out the ATAPI packet command successfully - and device sends data successfully. - - @retval EFI_DEVICE_ERROR - the device failed to send data. - -**/ -EFI_STATUS -AtapiPacketCommandIn ( - IN IDE_BLK_IO_DEV *IdeDev, - IN ATAPI_PACKET_COMMAND *Packet, - IN UINT16 *Buffer, - IN UINT32 ByteCount, - IN UINTN TimeOut - ) -{ - UINT16 *CommandIndex; - EFI_STATUS Status; - UINT32 Count; - - // - // Set all the command parameters by fill related registers. - // Before write to all the following registers, BSY and DRQ must be 0. + // Set all the command parameters by fill related registers. + // Before write to all the following registers, BSY and DRQ must be 0. // Status = DRQClear2 (IdeDev, ATAPITIMEOUT); if (EFI_ERROR (Status)) { @@ -542,35 +427,21 @@ AtapiPacketCommandIn ( // return PioReadWriteData (IdeDev, Buffer, ByteCount, 1, TimeOut); } - /** - This function is used to send out ATAPI commands conforms to the - Packet Command with PIO Data Out Protocol. - - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @param[in] *Packet - pointer pointing to ATAPI_PACKET_COMMAND data structure - which contains the contents of the command. - - @param[in] *Buffer - buffer contained data transferred from host to device. - - @param[in] ByteCount - data size in byte unit of the buffer. - - @param[in] TimeOut - this parameter is used to specify the timeout - value for the PioReadWriteData() function. - - @retval EFI_SUCCESS - send out the ATAPI packet command successfully - and device received data successfully. - - @retval EFI_DEVICE_ERROR - the device failed to send data. + This function is used to send out ATAPI commands conforms to the Packet Command + with PIO Data Out Protocol. + + @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + @param Packet pointer pointing to ATAPI_PACKET_COMMAND data structure + which contains the contents of the command. + @param Buffer buffer contained data transferred from host to device. + @param ByteCount data size in byte unit of the buffer. + @param TimeOut this parameter is used to specify the timeout value + for the PioReadWriteData() function. + @retval EFI_SUCCESS send out the ATAPI packet command successfully + and device received data successfully. + @retval EFI_DEVICE_ERROR the device failed to send data. **/ EFI_STATUS @@ -655,219 +526,249 @@ AtapiPacketCommandOut ( // return PioReadWriteData (IdeDev, Buffer, ByteCount, 0, TimeOut); } - /** - This function is called by either AtapiPacketCommandIn() or - AtapiPacketCommandOut(). It is used to transfer data between - host and device. The data direction is specified by the fourth - parameter. + Sends out ATAPI Inquiry Packet Command to the specified device. This command will + return INQUIRY data of the device. + + @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + + @retval EFI_SUCCESS Inquiry command completes successfully. + @retval EFI_DEVICE_ERROR Inquiry command failed. + + @note Parameter "IdeDev" will be updated in this function. + +**/ +EFI_STATUS +AtapiInquiry ( + IN IDE_BLK_IO_DEV *IdeDev + ) +{ + ATAPI_PACKET_COMMAND Packet; + EFI_STATUS Status; + ATAPI_INQUIRY_DATA *InquiryData; - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. + // + // prepare command packet for the ATAPI Inquiry Packet Command. + // + ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND)); + Packet.Inquiry.opcode = ATA_CMD_INQUIRY; + Packet.Inquiry.page_code = 0; + Packet.Inquiry.allocation_length = sizeof (ATAPI_INQUIRY_DATA); - @param[in] *Buffer - buffer contained data transferred between host and device. + InquiryData = AllocatePool (sizeof (ATAPI_INQUIRY_DATA)); + if (InquiryData == NULL) { + return EFI_DEVICE_ERROR; + } - @param[in] ByteCount - data size in byte unit of the buffer. + // + // Send command packet and get requested Inquiry data. + // + Status = AtapiPacketCommandIn ( + IdeDev, + &Packet, + (UINT16 *) InquiryData, + sizeof (ATAPI_INQUIRY_DATA), + ATAPITIMEOUT + ); + if (EFI_ERROR (Status)) { + gBS->FreePool (InquiryData); + return EFI_DEVICE_ERROR; + } - @param[in] Read - flag used to determine the data transfer direction. - Read equals 1, means data transferred from device to host; - Read equals 0, means data transferred from host to device. + IdeDev->InquiryData = InquiryData; - @param[in] TimeOut - timeout value for wait DRQ ready before each data - stream's transfer. + return EFI_SUCCESS; +} +/** + This function is called by DiscoverIdeDevice() during its device + identification. + Its main purpose is to get enough information for the device media + to fill in the Media data structure of the Block I/O Protocol interface. - @retval EFI_SUCCESS - data is transferred successfully. + There are 5 steps to reach such objective: + 1. Sends out the ATAPI Identify Command to the specified device. + Only ATAPI device responses to this command. If the command succeeds, + it returns the Identify data structure which filled with information + about the device. Since the ATAPI device contains removable media, + the only meaningful information is the device module name. + 2. Sends out ATAPI Inquiry Packet Command to the specified device. + This command will return inquiry data of the device, which contains + the device type information. + 3. Allocate sense data space for future use. We don't detect the media + presence here to improvement boot performance, especially when CD + media is present. The media detection will be performed just before + each BLK_IO read/write - @retval EFI_DEVICE_ERROR - the device failed to transfer data. + @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + + @retval EFI_SUCCESS Identify ATAPI device successfully. + @retval EFI_DEVICE_ERROR ATAPI Identify Device Command failed or device type + is not supported by this IDE driver. + @retval EFI_OUT_OF_RESOURCES Allocate memory for sense data failed + @note Parameter "IdeDev" will be updated in this function. **/ EFI_STATUS -PioReadWriteData ( - IN IDE_BLK_IO_DEV *IdeDev, - IN UINT16 *Buffer, - IN UINT32 ByteCount, - IN BOOLEAN Read, - IN UINTN TimeOut +ATAPIIdentify ( + IN IDE_BLK_IO_DEV *IdeDev ) { + EFI_IDENTIFY_DATA *AtapiIdentifyPointer; + UINT8 DeviceSelect; + EFI_STATUS Status; + // - // required transfer data in word unit. + // device select bit // - UINT32 RequiredWordCount; + DeviceSelect = (UINT8) ((IdeDev->Device) << 4); + AtapiIdentifyPointer = AllocatePool (sizeof (EFI_IDENTIFY_DATA)); + if (AtapiIdentifyPointer == NULL) { + return EFI_OUT_OF_RESOURCES; + } // - // actual transfer data in word unit. + // Send ATAPI Identify Command to get IDENTIFY data. // - UINT32 ActualWordCount; - UINT32 WordCount; - EFI_STATUS Status; - UINT16 *PtrBuffer; + Status = AtaPioDataIn ( + IdeDev, + (VOID *) AtapiIdentifyPointer, + sizeof (EFI_IDENTIFY_DATA), + ATA_CMD_IDENTIFY_DEVICE, + DeviceSelect, + 0, + 0, + 0, + 0 + ); + + if (EFI_ERROR (Status)) { + gBS->FreePool (AtapiIdentifyPointer); + return EFI_DEVICE_ERROR; + } + + IdeDev->IdData = AtapiIdentifyPointer; + PrintAtaModuleName (IdeDev); // - // No data transfer is premitted. + // Send ATAPI Inquiry Packet Command to get INQUIRY data. // - if (ByteCount == 0) { - return EFI_SUCCESS; + Status = AtapiInquiry (IdeDev); + if (EFI_ERROR (Status)) { + gBS->FreePool (IdeDev->IdData); + // + // Make sure the pIdData will not be freed again. + // + IdeDev->IdData = NULL; + return EFI_DEVICE_ERROR; } // - // for performance, we assert the ByteCount is an even number - // which is actually a resonable assumption - ASSERT((ByteCount%2) == 0); - - PtrBuffer = Buffer; - RequiredWordCount = ByteCount / 2; + // Get media removable info from INQUIRY data. // - // ActuralWordCount means the word count of data really transferred. + IdeDev->BlkIo.Media->RemovableMedia = (UINT8) ((IdeDev->InquiryData->RMB & 0x80) == 0x80); + // - ActualWordCount = 0; + // Identify device type via INQUIRY data. + // + switch (IdeDev->InquiryData->peripheral_type & 0x1f) { + + // + // Magnetic Disk + // + case 0x00: - while (ActualWordCount < RequiredWordCount) { - - // - // before each data transfer stream, the host should poll DRQ bit ready, - // to see whether indicates device is ready to transfer data. - // - Status = DRQReady2 (IdeDev, TimeOut); - if (EFI_ERROR (Status)) { - return CheckErrorStatus (IdeDev); - } - // - // read Status Register will clear interrupt + // device is LS120 or ZIP drive. // - IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status); + IdeDev->Type = IdeMagnetic; + IdeDev->BlkIo.Media->MediaId = 0; // - // get current data transfer size from Cylinder Registers. + // Give initial value // - WordCount = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb) << 8; - WordCount = WordCount | IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb); - WordCount = WordCount & 0xffff; - WordCount /= 2; + IdeDev->BlkIo.Media->MediaPresent = FALSE; - WordCount = MIN (WordCount, (RequiredWordCount - ActualWordCount)); + IdeDev->BlkIo.Media->LastBlock = 0; + IdeDev->BlkIo.Media->BlockSize = 0x200; + break; - if (Read) { - IDEReadPortWMultiple ( - IdeDev->PciIo, - IdeDev->IoPort->Data, - WordCount, - PtrBuffer - ); - } else { - IDEWritePortWMultiple ( - IdeDev->PciIo, - IdeDev->IoPort->Data, - WordCount, - PtrBuffer - ); - } + // + // CD-ROM + // + case 0x05: - PtrBuffer += WordCount; - ActualWordCount += WordCount; - } - - if (Read) { + IdeDev->Type = IdeCdRom; + IdeDev->BlkIo.Media->MediaId = 0; // - // In the case where the drive wants to send more data than we need to read, - // the DRQ bit will be set and cause delays from DRQClear2(). - // We need to read data from the drive until it clears DRQ so we can move on. + // Give initial value // - AtapiReadPendingData (IdeDev); - } + IdeDev->BlkIo.Media->MediaPresent = FALSE; + + IdeDev->BlkIo.Media->LastBlock = 0; + IdeDev->BlkIo.Media->BlockSize = 0x800; + IdeDev->BlkIo.Media->ReadOnly = TRUE; + break; // - // After data transfer is completed, normally, DRQ bit should clear. + // Tape // - Status = DRQClear2 (IdeDev, ATAPITIMEOUT); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } + case 0x01: // - // read status register to check whether error happens. + // WORM // - return CheckErrorStatus (IdeDev); -} - -/** - Sends out ATAPI Test Unit Ready Packet Command to the specified device - to find out whether device is accessible. - - @param[in] *IdeDev Pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - @param[in] *SResult Sense result for this packet command. - - @retval EFI_SUCCESS Device is accessible. - @retval EFI_DEVICE_ERROR Device is not accessible. - -**/ -EFI_STATUS -AtapiTestUnitReady ( - IN IDE_BLK_IO_DEV *IdeDev, - OUT SENSE_RESULT *SResult - ) -{ - ATAPI_PACKET_COMMAND Packet; - EFI_STATUS Status; - UINTN SenseCount; - + case 0x04: + // - // fill command packet + // Optical // - ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND)); - Packet.TestUnitReady.opcode = ATA_CMD_TEST_UNIT_READY; + case 0x07: + + default: + IdeDev->Type = IdeUnknown; + gBS->FreePool (IdeDev->IdData); + gBS->FreePool (IdeDev->InquiryData); + // + // Make sure the pIdData and pInquiryData will not be freed again. + // + IdeDev->IdData = NULL; + IdeDev->InquiryData = NULL; + return EFI_DEVICE_ERROR; + } // - // send command packet + // original sense data numbers // - Status = AtapiPacketCommandIn (IdeDev, &Packet, NULL, 0, ATAPITIMEOUT); - if (EFI_ERROR (Status)) { - return Status; - } + IdeDev->SenseDataNumber = 20; - Status = AtapiRequestSense (IdeDev, &SenseCount); - if (EFI_ERROR (Status)) { - return Status; + IdeDev->SenseData = AllocatePool (IdeDev->SenseDataNumber * sizeof (ATAPI_REQUEST_SENSE_DATA)); + if (IdeDev->SenseData == NULL) { + gBS->FreePool (IdeDev->IdData); + gBS->FreePool (IdeDev->InquiryData); + // + // Make sure the pIdData and pInquiryData will not be freed again. + // + IdeDev->IdData = NULL; + IdeDev->InquiryData = NULL; + return EFI_OUT_OF_RESOURCES; } - ParseSenseData (IdeDev, SenseCount, SResult); return EFI_SUCCESS; } - /** - Sends out ATAPI Request Sense Packet Command to the specified device. - This command will return all the current Sense data in the device. - This function will pack all the Sense data in one single buffer. - - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @param[out] **SenseBuffers - allocated in this function, and freed by the calling function. - This buffer is used to accommodate all the sense data returned - by the device. - - @param[out] *BufUnit - record the unit size of the sense data block in the SenseBuffers, - - @param[out] *BufNumbers - record the number of units in the SenseBuffers. - - @retval EFI_SUCCESS - Request Sense command completes successfully. - - @retval EFI_DEVICE_ERROR - Request Sense command failed. - + Sends out ATAPI Request Sense Packet Command to the specified device. This command + will return all the current Sense data in the device. This function will pack + all the Sense data in one single buffer. + + @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + @param SenseCounts allocated in this function, and freed by the calling function. + This buffer is used to accommodate all the sense data returned + by the device. + + @retval EFI_SUCCESS Request Sense command completes successfully. + @retval EFI_DEVICE_ERROR Request Sense command failed. **/ EFI_STATUS AtapiRequestSense ( @@ -924,30 +825,148 @@ AtapiRequestSense ( } } - (*SenseCounts)++; - // - // We limit MAX sense data count to 20 in order to avoid dead loop. Some - // incompatible ATAPI devices don't retrive NO_SENSE when there is no media. - // In this case, dead loop occurs if we don't have a gatekeeper. 20 is - // supposed to be large enough for any ATAPI device. - // - if ((Sense->sense_key != ATA_SK_NO_SENSE) && ((*SenseCounts) < 20)) { - // - // Ptr is word-based pointer - // - Ptr += (sizeof (ATAPI_REQUEST_SENSE_DATA) + 1) >> 1; + (*SenseCounts)++; + // + // We limit MAX sense data count to 20 in order to avoid dead loop. Some + // incompatible ATAPI devices don't retrive NO_SENSE when there is no media. + // In this case, dead loop occurs if we don't have a gatekeeper. 20 is + // supposed to be large enough for any ATAPI device. + // + if ((Sense->sense_key != ATA_SK_NO_SENSE) && ((*SenseCounts) < 20)) { + // + // Ptr is word-based pointer + // + Ptr += (sizeof (ATAPI_REQUEST_SENSE_DATA) + 1) >> 1; + + } else { + // + // when no sense key, skip out the loop + // + FetchSenseData = FALSE; + } + } + + return EFI_SUCCESS; +} +/** + This function is used to parse sense data. Only the first sense data is honoured + + @param IdeDev Indicates the calling context. + @param SenseCount Count of sense data. + @param Result The parsed result. + + @retval EFI_SUCCESS Successfully parsed. + @retval EFI_INVALID_PARAMETER Count of sense data is zero. + +**/ +EFI_STATUS +ParseSenseData ( + IN IDE_BLK_IO_DEV *IdeDev, + IN UINTN SenseCount, + OUT SENSE_RESULT *Result + ) +{ + ATAPI_REQUEST_SENSE_DATA *SenseData; + + if (SenseCount == 0) { + return EFI_INVALID_PARAMETER; + } + + // + // Only use the first sense data + // + SenseData = IdeDev->SenseData; + *Result = SenseOtherSense; + + switch (SenseData->sense_key) { + case ATA_SK_NO_SENSE: + *Result = SenseNoSenseKey; + break; + case ATA_SK_NOT_READY: + switch (SenseData->addnl_sense_code) { + case ATA_ASC_NO_MEDIA: + *Result = SenseNoMedia; + break; + case ATA_ASC_MEDIA_UPSIDE_DOWN: + *Result = SenseMediaError; + break; + case ATA_ASC_NOT_READY: + if (SenseData->addnl_sense_code_qualifier == ATA_ASCQ_IN_PROGRESS) { + *Result = SenseDeviceNotReadyNeedRetry; + } else { + *Result = SenseDeviceNotReadyNoRetry; + } + break; + } + break; + case ATA_SK_UNIT_ATTENTION: + if (SenseData->addnl_sense_code == ATA_ASC_MEDIA_CHANGE) { + *Result = SenseMediaChange; + } + break; + case ATA_SK_MEDIUM_ERROR: + switch (SenseData->addnl_sense_code) { + case ATA_ASC_MEDIA_ERR1: + case ATA_ASC_MEDIA_ERR2: + case ATA_ASC_MEDIA_ERR3: + case ATA_ASC_MEDIA_ERR4: + *Result = SenseMediaError; + break; + } + break; + default: + break; + } + + return EFI_SUCCESS; +} + +/** + Sends out ATAPI Test Unit Ready Packet Command to the specified device + to find out whether device is accessible. + + @param IdeDev Pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + @param SResult Sense result for this packet command. + + @retval EFI_SUCCESS Device is accessible. + @retval EFI_DEVICE_ERROR Device is not accessible. + +**/ +EFI_STATUS +AtapiTestUnitReady ( + IN IDE_BLK_IO_DEV *IdeDev, + OUT SENSE_RESULT *SResult + ) +{ + ATAPI_PACKET_COMMAND Packet; + EFI_STATUS Status; + UINTN SenseCount; + + // + // fill command packet + // + ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND)); + Packet.TestUnitReady.opcode = ATA_CMD_TEST_UNIT_READY; + + // + // send command packet + // + Status = AtapiPacketCommandIn (IdeDev, &Packet, NULL, 0, ATAPITIMEOUT); + if (EFI_ERROR (Status)) { + return Status; + } - } else { - // - // when no sense key, skip out the loop - // - FetchSenseData = FALSE; - } + Status = AtapiRequestSense (IdeDev, &SenseCount); + if (EFI_ERROR (Status)) { + return Status; } + ParseSenseData (IdeDev, SenseCount, SResult); return EFI_SUCCESS; } + /** Sends out ATAPI Read Capacity Packet Command to the specified device. This command will return the information regarding the capacity of the @@ -959,16 +978,17 @@ AtapiRequestSense ( if the Read Capacity Command failed, the Sense data must be requested and be analyzed to determine if the Read Capacity Command should retry. - @param[in] *IdeDev Pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - @param[in] SResult Sense result for this packet command + @param IdeDev Pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + @param SResult Sense result for this packet command @retval EFI_SUCCESS Read Capacity Command finally completes successfully. @retval EFI_DEVICE_ERROR Read Capacity Command failed because of device error. + @retval EFI_NOT_READY Operation succeeds but returned capacity is 0 @note Parameter "IdeDev" will be updated in this function. - TODO: EFI_NOT_READY - add return value to function comment + **/ EFI_STATUS AtapiReadCapacity ( @@ -1038,7 +1058,7 @@ AtapiReadCapacity ( (Data.LastLba1 << 8) | Data.LastLba0; - IdeDev->BlkIo.Media->MediaPresent = TRUE; + IdeDev->BlkIo.Media->MediaPresent = TRUE; IdeDev->BlkIo.Media->ReadOnly = TRUE; @@ -1088,30 +1108,70 @@ AtapiReadCapacity ( return EFI_DEVICE_ERROR; } } +/** + This function is used to test the current media write-protected or not residing + in the LS-120 drive or ZIP drive. + @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + @param WriteProtected if True, current media is write protected. + if FALSE, current media is writable + + @retval EFI_SUCCESS The media write-protected status is achieved successfully + @retval EFI_DEVICE_ERROR Get Media Status Command is failed. +**/ +EFI_STATUS +IsLS120orZipWriteProtected ( + IN IDE_BLK_IO_DEV *IdeDev, + OUT BOOLEAN *WriteProtected + ) +{ + EFI_STATUS Status; + + *WriteProtected = FALSE; + + Status = LS120EnableMediaStatus (IdeDev, TRUE); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + // + // the Get Media Status Command is only valid + // if a Set Features/Enable Media Status Command has been priviously issued. + // + if (LS120GetMediaStatus (IdeDev) == EFI_WRITE_PROTECTED) { + + *WriteProtected = TRUE; + } else { + + *WriteProtected = FALSE; + } + + // + // After Get Media Status Command completes, + // Set Features/Disable Media Command should be sent. + // + Status = LS120EnableMediaStatus (IdeDev, FALSE); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} /** - Used before read/write blocks from/to ATAPI device media. - Since ATAPI device media is removable, it is necessary to detect - whether media is present and get current present media's - information, and if media has been changed, Block I/O Protocol - need to be reinstalled. - - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @param[out] *MediaChange - return value that indicates if the media of the device has been - changed. - - @retval EFI_SUCCESS - media found successfully. - - @retval EFI_DEVICE_ERROR - any error encounters during media detection. - - @retval EFI_NO_MEDIA - media not found. + Used before read/write blocks from/to ATAPI device media. Since ATAPI device + media is removable, it is necessary to detect whether media is present and + get current present media's information, and if media has been changed, Block + I/O Protocol need to be reinstalled. + + @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + @param MediaChange return value that indicates if the media of the device has been + changed. + + @retval EFI_SUCCESS media found successfully. + @retval EFI_DEVICE_ERROR any error encounters during media detection. + @retval EFI_NO_MEDIA media not found. @note parameter IdeDev may be updated in this function. @@ -1356,22 +1416,14 @@ AtapiDetectMedia ( 65536. This is the main difference between READ(10) and READ(12) Command. The maximum number of blocks in READ(12) is 2 power 32. - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @param[in] *Buffer - A pointer to the destination buffer for the data. - - @param[in] Lba - The starting logical block address to read from - on the device media. + @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + @param Buffer A pointer to the destination buffer for the data. + @param Lba The starting logical block address to read from on the + device media. + @param NumberOfBlocks The number of transfer data blocks. - @param[in] NumberOfBlocks - The number of transfer data blocks. - - @return status is fully dependent on the return status - of AtapiPacketCommandIn() function. + @return status is fully dependent on the return status of AtapiPacketCommandIn() function. **/ EFI_STATUS @@ -1481,22 +1533,14 @@ AtapiReadSectors ( unit. The maximum number of blocks that can be transferred once is 65536. - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. - - @param[in] *Buffer - A pointer to the source buffer for the data. - - @param[in] Lba - The starting logical block address to write onto - the device media. - - @param[in] NumberOfBlocks - The number of transfer data blocks. - - @return status is fully dependent on the return status - of AtapiPacketCommandOut() function. + @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. + @param Buffer A pointer to the source buffer for the data. + @param Lba The starting logical block address to write onto + the device media. + @param NumberOfBlocks The number of transfer data blocks. + + @return status is fully dependent on the return status of AtapiPacketCommandOut() function. **/ EFI_STATUS @@ -1592,7 +1636,6 @@ AtapiWriteSectors ( return Status; } - /** This function is used to implement the Soft Reset on the specified ATAPI device. Different from the AtaSoftReset(), here reset is a ATA @@ -1605,15 +1648,11 @@ AtapiWriteSectors ( This function is called by IdeBlkIoReset(), a interface function of Block I/O protocol. - @param[in] *IdeDev - pointer pointing to IDE_BLK_IO_DEV data structure, used - to record all the information of the IDE device. + @param IdeDev pointer pointing to IDE_BLK_IO_DEV data structure, used + to record all the information of the IDE device. - @retval EFI_SUCCESS - Soft reset completes successfully. - - @retval EFI_DEVICE_ERROR - Any step during the reset process is failed. + @retval EFI_SUCCESS Soft reset completes successfully. + @retval EFI_DEVICE_ERROR Any step during the reset process is failed. **/ EFI_STATUS @@ -1657,51 +1696,29 @@ AtapiSoftReset ( This function is the ATAPI implementation for ReadBlocks in the Block I/O Protocol interface. - @param[in] *IdeBlkIoDev - Indicates the calling context. - - @param[in] MediaId - The media id that the read request is for. - - @param[in] LBA - The starting logical block address to read from - on the device. - - @param[in] BufferSize - The size of the Buffer in bytes. This must be a - multiple of the intrinsic block size of the device. - - @param[out] *Buffer - A pointer to the destination buffer for the data. - The caller is responsible for either having implicit - or explicit ownership of the memory that data is read into. - - @retval EFI_SUCCESS - Read Blocks successfully. - - @retval EFI_DEVICE_ERROR - Read Blocks failed. - - @retval EFI_NO_MEDIA - There is no media in the device. + @param IdeBlkIoDevice Indicates the calling context. + @param MediaId The media id that the read request is for. + @param Lba The starting logical block address to read from on the device. + @param BufferSize The size of the Buffer in bytes. This must be a multiple + of the intrinsic block size of the device. + @param Buffer A pointer to the destination buffer for the data. The caller + is responsible for either having implicit or explicit + ownership of the memory that data is read into. - @retval EFI_MEDIA_CHANGED - The MediaId is not for the current media. - - @retval EFI_BAD_BUFFER_SIZE - The BufferSize parameter is not a multiple of the - intrinsic block size of the device. - - @retval EFI_INVALID_PARAMETER - The read request contains LBAs that are not valid, - or the data buffer is not valid. - + @retval EFI_SUCCESS Read Blocks successfully. + @retval EFI_DEVICE_ERROR Read Blocks failed. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_MEDIA_CHANGED The MediaId is not for the current media. + @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of the + intrinsic block size of the device. + @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid, + or the data buffer is not valid. **/ EFI_STATUS AtapiBlkIoReadBlocks ( IN IDE_BLK_IO_DEV *IdeBlkIoDevice, IN UINT32 MediaId, - IN EFI_LBA LBA, + IN EFI_LBA Lba, IN UINTN BufferSize, OUT VOID *Buffer ) @@ -1767,11 +1784,11 @@ AtapiBlkIoReadBlocks ( return EFI_BAD_BUFFER_SIZE; } - if (LBA > Media->LastBlock) { + if (Lba > Media->LastBlock) { return EFI_INVALID_PARAMETER; } - if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) { + if ((Lba + NumberOfBlocks - 1) > Media->LastBlock) { return EFI_INVALID_PARAMETER; } @@ -1783,7 +1800,7 @@ AtapiBlkIoReadBlocks ( // if all the parameters are valid, then perform read sectors command // to transfer data from device to host. // - Status = AtapiReadSectors (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks); + Status = AtapiReadSectors (IdeBlkIoDevice, Buffer, Lba, NumberOfBlocks); if (EFI_ERROR (Status)) { return EFI_DEVICE_ERROR; } @@ -1795,9 +1812,9 @@ AtapiBlkIoReadBlocks ( // // save the first block to the cache for performance // - if (LBA == 0 && !IdeBlkIoDevice->Cache) { + if (Lba == 0 && (IdeBlkIoDevice->Cache == NULL)) { IdeBlkIoDevice->Cache = AllocatePool (BlockSize); - if (IdeBlkIoDevice != NULL) { + if (IdeBlkIoDevice->Cache!= NULL) { CopyMem ((UINT8 *) IdeBlkIoDevice->Cache, (UINT8 *) Buffer, BlockSize); } } @@ -1805,59 +1822,35 @@ AtapiBlkIoReadBlocks ( return EFI_SUCCESS; } - /** This function is the ATAPI implementation for WriteBlocks in the Block I/O Protocol interface. - @param[in] *This - Indicates the calling context. - - @param[in] MediaId - The media id that the write request is for. - - @param[in] LBA - The starting logical block address to write onto - the device. - - @param[in] BufferSize - The size of the Buffer in bytes. This must be a - multiple of the intrinsic block size of the device. - - @param[out] *Buffer - A pointer to the source buffer for the data. - The caller is responsible for either having implicit - or explicit ownership of the memory that data is - written from. - - @retval EFI_SUCCESS - Write Blocks successfully. - - @retval EFI_DEVICE_ERROR - Write Blocks failed. - - @retval EFI_NO_MEDIA - There is no media in the device. - - @retval EFI_MEDIA_CHANGE - The MediaId is not for the current media. - - @retval EFI_BAD_BUFFER_SIZE - The BufferSize parameter is not a multiple of the - intrinsic block size of the device. - - @retval EFI_INVALID_PARAMETER - The write request contains LBAs that are not valid, - or the data buffer is not valid. - - TODO: EFI_MEDIA_CHANGED - add return value to function comment - TODO: EFI_WRITE_PROTECTED - add return value to function comment + @param IdeBlkIoDevice Indicates the calling context. + @param MediaId The media id that the write request is for. + @param Lba The starting logical block address to write onto the device. + @param BufferSize The size of the Buffer in bytes. This must be a multiple + of the intrinsic block size of the device. + @param Buffer A pointer to the source buffer for the data. The caller + is responsible for either having implicit or explicit ownership + of the memory that data is written from. + + @retval EFI_SUCCESS Write Blocks successfully. + @retval EFI_DEVICE_ERROR Write Blocks failed. + @retval EFI_NO_MEDIA There is no media in the device. + @retval EFI_MEDIA_CHANGE The MediaId is not for the current media. + @retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of the + intrinsic block size of the device. + @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid, + or the data buffer is not valid. + + @retval EFI_WRITE_PROTECTED The write protected is enabled or the media does not support write **/ EFI_STATUS AtapiBlkIoWriteBlocks ( IN IDE_BLK_IO_DEV *IdeBlkIoDevice, IN UINT32 MediaId, - IN EFI_LBA LBA, + IN EFI_LBA Lba, IN UINTN BufferSize, OUT VOID *Buffer ) @@ -1869,7 +1862,7 @@ AtapiBlkIoWriteBlocks ( EFI_STATUS Status; BOOLEAN MediaChange; - if (LBA == 0 && IdeBlkIoDevice->Cache) { + if (Lba == 0 && IdeBlkIoDevice->Cache != NULL) { gBS->FreePool (IdeBlkIoDevice->Cache); IdeBlkIoDevice->Cache = NULL; } @@ -1890,7 +1883,7 @@ AtapiBlkIoWriteBlocks ( Status = AtapiDetectMedia (IdeBlkIoDevice, &MediaChange); if (EFI_ERROR (Status)) { - if (LBA == 0 && IdeBlkIoDevice->Cache) { + if (Lba == 0 && IdeBlkIoDevice->Cache != NULL) { gBS->FreePool (IdeBlkIoDevice->Cache); IdeBlkIoDevice->Cache = NULL; } @@ -1906,7 +1899,7 @@ AtapiBlkIoWriteBlocks ( if (!(Media->MediaPresent)) { - if (LBA == 0 && IdeBlkIoDevice->Cache) { + if (Lba == 0 && IdeBlkIoDevice->Cache != NULL) { gBS->FreePool (IdeBlkIoDevice->Cache); IdeBlkIoDevice->Cache = NULL; } @@ -1915,7 +1908,7 @@ AtapiBlkIoWriteBlocks ( if ((MediaId != Media->MediaId) || MediaChange) { - if (LBA == 0 && IdeBlkIoDevice->Cache) { + if (Lba == 0 && IdeBlkIoDevice->Cache != NULL) { gBS->FreePool (IdeBlkIoDevice->Cache); IdeBlkIoDevice->Cache = NULL; } @@ -1930,11 +1923,11 @@ AtapiBlkIoWriteBlocks ( return EFI_BAD_BUFFER_SIZE; } - if (LBA > Media->LastBlock) { + if (Lba > Media->LastBlock) { return EFI_INVALID_PARAMETER; } - if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) { + if ((Lba + NumberOfBlocks - 1) > Media->LastBlock) { return EFI_INVALID_PARAMETER; } @@ -1946,7 +1939,7 @@ AtapiBlkIoWriteBlocks ( // if all the parameters are valid, // then perform write sectors command to transfer data from host to device. // - Status = AtapiWriteSectors (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks); + Status = AtapiWriteSectors (IdeBlkIoDevice, Buffer, Lba, NumberOfBlocks); if (EFI_ERROR (Status)) { return EFI_DEVICE_ERROR; } @@ -1955,162 +1948,5 @@ AtapiBlkIoWriteBlocks ( } -/** - This function is used to parse sense data. Only the first - sense data is honoured. - - @param[in] IdeDev Indicates the calling context. - @param[in] SenseCount Count of sense data. - @param[out] Result The parsed result. - - @retval EFI_SUCCESS Successfully parsed. - @retval EFI_INVALID_PARAMETER Count of sense data is zero. - -**/ -EFI_STATUS -ParseSenseData ( - IN IDE_BLK_IO_DEV *IdeDev, - IN UINTN SenseCount, - OUT SENSE_RESULT *Result - ) -{ - ATAPI_REQUEST_SENSE_DATA *SenseData; - - if (SenseCount == 0) { - return EFI_INVALID_PARAMETER; - } - - // - // Only use the first sense data - // - SenseData = IdeDev->SenseData; - *Result = SenseOtherSense; - - switch (SenseData->sense_key) { - case ATA_SK_NO_SENSE: - *Result = SenseNoSenseKey; - break; - case ATA_SK_NOT_READY: - switch (SenseData->addnl_sense_code) { - case ATA_ASC_NO_MEDIA: - *Result = SenseNoMedia; - break; - case ATA_ASC_MEDIA_UPSIDE_DOWN: - *Result = SenseMediaError; - break; - case ATA_ASC_NOT_READY: - if (SenseData->addnl_sense_code_qualifier == ATA_ASCQ_IN_PROGRESS) { - *Result = SenseDeviceNotReadyNeedRetry; - } else { - *Result = SenseDeviceNotReadyNoRetry; - } - break; - } - break; - case ATA_SK_UNIT_ATTENTION: - if (SenseData->addnl_sense_code == ATA_ASC_MEDIA_CHANGE) { - *Result = SenseMediaChange; - } - break; - case ATA_SK_MEDIUM_ERROR: - switch (SenseData->addnl_sense_code) { - case ATA_ASC_MEDIA_ERR1: - case ATA_ASC_MEDIA_ERR2: - case ATA_ASC_MEDIA_ERR3: - case ATA_ASC_MEDIA_ERR4: - *Result = SenseMediaError; - break; - } - break; - default: - break; - } - - return EFI_SUCCESS; -} - -/** - This function reads the pending data in the device. - - @param[in] IdeDev Indicates the calling context. - - @retval EFI_SUCCESS Successfully read. - @retval EFI_NOT_READY The BSY is set avoiding reading. - -**/ -EFI_STATUS -AtapiReadPendingData ( - IN IDE_BLK_IO_DEV *IdeDev - ) -{ - UINT8 AltRegister; - UINT16 TempWordBuffer; - - AltRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.AltStatus); - if ((AltRegister & ATA_STSREG_BSY) == ATA_STSREG_BSY) { - return EFI_NOT_READY; - } - if ((AltRegister & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) { - TempWordBuffer = IDEReadPortB (IdeDev->PciIo,IdeDev->IoPort->Alt.AltStatus); - while ((TempWordBuffer & (ATA_STSREG_BSY | ATA_STSREG_DRQ)) == ATA_STSREG_DRQ) { - IDEReadPortWMultiple ( - IdeDev->PciIo, - IdeDev->IoPort->Data, - 1, - &TempWordBuffer - ); - TempWordBuffer = IDEReadPortB (IdeDev->PciIo,IdeDev->IoPort->Alt.AltStatus); - } - } - return EFI_SUCCESS; -} - -/** - TODO: Add function description - - @param IdeDev TODO: add argument description - @param WriteProtected TODO: add argument description - - @retval EFI_DEVICE_ERROR TODO: Add description for return value - @retval EFI_DEVICE_ERROR TODO: Add description for return value - @retval EFI_SUCCESS TODO: Add description for return value - -**/ -EFI_STATUS -IsLS120orZipWriteProtected ( - IN IDE_BLK_IO_DEV *IdeDev, - OUT BOOLEAN *WriteProtected - ) -{ - EFI_STATUS Status; - - *WriteProtected = FALSE; - - Status = LS120EnableMediaStatus (IdeDev, TRUE); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - // - // the Get Media Status Command is only valid - // if a Set Features/Enable Media Status Command has been priviously issued. - // - if (LS120GetMediaStatus (IdeDev) == EFI_WRITE_PROTECTED) { - - *WriteProtected = TRUE; - } else { - - *WriteProtected = FALSE; - } - // - // After Get Media Status Command completes, - // Set Features/Disable Media Command should be sent. - // - Status = LS120EnableMediaStatus (IdeDev, FALSE); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - return EFI_SUCCESS; -}