/** Get the parameters for the USB mass storage media. This function get the parameters for the USB mass storage media, It is used both to initialize the media during the Start() phase of Driver Binding Protocol and to re-initialize it when the media is changed. Althought the RemoveableMedia is unlikely to change, it is also included here. @param UsbMass The device to retrieve disk gemotric. @retval EFI_SUCCESS The disk gemotric is successfully retrieved. @retval Other Failed to get the parameters. **/ EFI_STATUS UsbBootGetParams ( IN USB_MASS_DEVICE *UsbMass ) { EFI_BLOCK_IO_MEDIA *Media; EFI_STATUS Status; Media = &(UsbMass->BlockIoMedia); Status = UsbBootInquiry (UsbMass); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "UsbBootGetParams: UsbBootInquiry (%r)\n", Status)); return Status; } // // Don't use the Removable bit in inquiry data to test whether the media // is removable because many flash disks wrongly set this bit. // if ((UsbMass->Pdt == USB_PDT_CDROM) || (UsbMass->Pdt == USB_PDT_OPTICAL)) { // // CD-Rom device and Non-CD optical device // UsbMass->OpticalStorage = TRUE; // // Default value 2048 Bytes, in case no media present at first time // Media->BlockSize = 0x0800; } Status = UsbBootDetectMedia (UsbMass); return Status; }
/** Get the parameters for the USB mass storage media. This function get the parameters for the USB mass storage media, It is used both to initialize the media during the Start() phase of Driver Binding Protocol and to re-initialize it when the media is changed. Althought the RemoveableMedia is unlikely to change, it is also included here. @param UsbMass The device to retrieve disk gemotric. @retval EFI_SUCCESS The disk gemotric is successfully retrieved. @retval Other Failed to get the parameters. **/ EFI_STATUS UsbBootGetParams ( IN USB_MASS_DEVICE *UsbMass ) { EFI_BLOCK_IO_MEDIA *Media; EFI_STATUS Status; Media = &(UsbMass->BlockIoMedia); Status = UsbBootInquiry (UsbMass); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "UsbBootGetParams: UsbBootInquiry (%r)\n", Status)); return Status; } // // According to USB Mass Storage Specification for Bootability, only following // 4 Peripheral Device Types are in spec. // if ((UsbMass->Pdt != USB_PDT_DIRECT_ACCESS) && (UsbMass->Pdt != USB_PDT_CDROM) && (UsbMass->Pdt != USB_PDT_OPTICAL) && (UsbMass->Pdt != USB_PDT_SIMPLE_DIRECT)) { DEBUG ((EFI_D_ERROR, "UsbBootGetParams: Found an unsupported peripheral type[%d]\n", UsbMass->Pdt)); return EFI_UNSUPPORTED; } // // Don't use the Removable bit in inquiry data to test whether the media // is removable because many flash disks wrongly set this bit. // if ((UsbMass->Pdt == USB_PDT_CDROM) || (UsbMass->Pdt == USB_PDT_OPTICAL)) { // // CD-Rom device and Non-CD optical device // UsbMass->OpticalStorage = TRUE; // // Default value 2048 Bytes, in case no media present at first time // Media->BlockSize = 0x0800; } Status = UsbBootDetectMedia (UsbMass); return Status; }
/** Reads the requested number of blocks from the device. This function implements EFI_BLOCK_IO_PROTOCOL.ReadBlocks(). It reads the requested number of blocks from the device. All the blocks are read, or an error is returned. @param This Indicates a pointer to 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 buffer. @retval EFI_SUCCESS The data was read correctly from the device. @retval EFI_DEVICE_ERROR The device reported an error while attempting to perform the read operation. @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 buffer is not on proper alignment. **/ EFI_STATUS EFIAPI UsbMassReadBlocks ( IN EFI_BLOCK_IO_PROTOCOL *This, IN UINT32 MediaId, IN EFI_LBA Lba, IN UINTN BufferSize, OUT VOID *Buffer ) { USB_MASS_DEVICE *UsbMass; EFI_BLOCK_IO_MEDIA *Media; EFI_STATUS Status; EFI_TPL OldTpl; UINTN TotalBlock; // // Raise TPL to TPL_CALLBACK to serialize all its operations // to protect shared data structures. // OldTpl = gBS->RaiseTPL (TPL_CALLBACK); UsbMass = USB_MASS_DEVICE_FROM_BLOCK_IO (This); Media = &UsbMass->BlockIoMedia; // // If it is a removable media, such as CD-Rom or Usb-Floppy, // need to detect the media before each read/write. While some of // Usb-Flash is marked as removable media. // if (Media->RemovableMedia) { Status = UsbBootDetectMedia (UsbMass); if (EFI_ERROR (Status)) { goto ON_EXIT; } } if (!(Media->MediaPresent)) { Status = EFI_NO_MEDIA; goto ON_EXIT; } if (MediaId != Media->MediaId) { Status = EFI_MEDIA_CHANGED; goto ON_EXIT; } if (BufferSize == 0) { Status = EFI_SUCCESS; goto ON_EXIT; } if (Buffer == NULL) { Status = EFI_INVALID_PARAMETER; goto ON_EXIT; } // // BufferSize must be a multiple of the intrinsic block size of the device. // if ((BufferSize % Media->BlockSize) != 0) { Status = EFI_BAD_BUFFER_SIZE; goto ON_EXIT; } TotalBlock = BufferSize / Media->BlockSize; // // Make sure the range to read is valid. // if (Lba + TotalBlock - 1 > Media->LastBlock) { Status = EFI_INVALID_PARAMETER; goto ON_EXIT; } if (UsbMass->Cdb16Byte) { Status = UsbBootReadBlocks16 (UsbMass, Lba, TotalBlock, Buffer); } else { Status = UsbBootReadBlocks (UsbMass, (UINT32) Lba, TotalBlock, Buffer); } if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "UsbMassReadBlocks: UsbBootReadBlocks (%r) -> Reset\n", Status)); UsbMassReset (This, TRUE); } ON_EXIT: gBS->RestoreTPL (OldTpl); return Status; }