/** Common report status code interface. @param This Pointer of FDC_BLK_IO_DEV instance @param Read Read or write operation when error occurrs **/ VOID FddReportStatus ( IN EFI_BLOCK_IO_PROTOCOL *This, IN BOOLEAN Read ) { FDC_BLK_IO_DEV *FdcDev; FdcDev = FDD_BLK_IO_FROM_THIS (This); REPORT_STATUS_CODE_WITH_DEVICE_PATH ( EFI_ERROR_CODE, ((Read) ? EFI_P_EC_INPUT_ERROR : EFI_P_EC_OUTPUT_ERROR) | EFI_PERIPHERAL_REMOVABLE_MEDIA, FdcDev->DevicePath ); }
/** Reset the Block Device. @param This Indicates a pointer to the calling context. @param ExtendedVerification Driver may perform diagnostics on reset. @retval EFI_SUCCESS The device was reset. @retval EFI_DEVICE_ERROR The device is not functioning properly and could not be reset. **/ EFI_STATUS EFIAPI FdcReset ( IN EFI_BLOCK_IO_PROTOCOL *This, IN BOOLEAN ExtendedVerification ) { FDC_BLK_IO_DEV *FdcDev; // // Reset the Floppy Disk Controller // FdcDev = FDD_BLK_IO_FROM_THIS (This); REPORT_STATUS_CODE_WITH_DEVICE_PATH ( EFI_PROGRESS_CODE, EFI_P_PC_RESET | EFI_PERIPHERAL_REMOVABLE_MEDIA, FdcDev->DevicePath ); return FddReset (FdcDev); }
/** Stop this driver on ControllerHandle. @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. @param[in] ControllerHandle A handle to the device being stopped. The handle must support a bus specific I/O protocol for the driver to use to stop the device. @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer. @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL if NumberOfChildren is 0. @retval EFI_SUCCESS The device was stopped. @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error. **/ EFI_STATUS EFIAPI FdcControllerDriverStop ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer ) { EFI_STATUS Status; EFI_BLOCK_IO_PROTOCOL *BlkIo; FDC_BLK_IO_DEV *FdcDev; // // Ignore NumberOfChildren since this is a device driver // // // Get the Block I/O Protocol on Controller // Status = gBS->OpenProtocol ( Controller, &gEfiBlockIoProtocolGuid, (VOID **) &BlkIo, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); if (EFI_ERROR (Status)) { return Status; } // // Get the floppy drive device's Device structure // FdcDev = FDD_BLK_IO_FROM_THIS (BlkIo); // // Report disable progress code // REPORT_STATUS_CODE_WITH_DEVICE_PATH ( EFI_PROGRESS_CODE, EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_DISABLE, FdcDev->DevicePath ); // // Uninstall the Block I/O Protocol // Status = gBS->UninstallProtocolInterface ( Controller, &gEfiBlockIoProtocolGuid, &FdcDev->BlkIo ); if (EFI_ERROR (Status)) { return Status; } // // Close the event for turning the motor off // gBS->CloseEvent (FdcDev->Event); // // Turn the motor off on the floppy drive device // FddTimerProc (FdcDev->Event, FdcDev); // // Close the device path protocol // gBS->CloseProtocol ( Controller, &gEfiDevicePathProtocolGuid, This->DriverBindingHandle, Controller ); // // Close the ISA I/O Protocol // gBS->CloseProtocol ( Controller, &gEfiIsaIoProtocolGuid, This->DriverBindingHandle, Controller ); // // Free the controller list if needed // FdcDev->ControllerState->NumberOfDrive--; // // Free the cache if one was allocated // FdcFreeCache (FdcDev); // // Free the floppy drive device's device structure // FreeUnicodeStringTable (FdcDev->ControllerNameTable); FreePool (FdcDev); return EFI_SUCCESS; }
/** Retrieves a Unicode string that is the user readable name of the controller that is being managed by a driver. This function retrieves the user readable name of the controller specified by ControllerHandle and ChildHandle in the form of a Unicode string. If the driver specified by This has a user readable name in the language specified by Language, then a pointer to the controller name is returned in ControllerName, and EFI_SUCCESS is returned. If the driver specified by This is not currently managing the controller specified by ControllerHandle and ChildHandle, then EFI_UNSUPPORTED is returned. If the driver specified by This does not support the language specified by Language, then EFI_UNSUPPORTED is returned. @param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or EFI_COMPONENT_NAME_PROTOCOL instance. @param[in] ControllerHandle The handle of a controller that the driver specified by This is managing. This handle specifies the controller whose name is to be returned. @param[in] ChildHandle The handle of the child controller to retrieve the name of. This is an optional parameter that may be NULL. It will be NULL for device drivers. It will also be NULL for a bus drivers that wish to retrieve the name of the bus controller. It will not be NULL for a bus driver that wishes to retrieve the name of a child controller. @param[in] Language A pointer to a Null-terminated ASCII string array indicating the language. This is the language of the driver name that the caller is requesting, and it must match one of the languages specified in SupportedLanguages. The number of languages supported by a driver is up to the driver writer. Language is specified in RFC 4646 or ISO 639-2 language code format. @param[out] ControllerName A pointer to the Unicode string to return. This Unicode string is the name of the controller specified by ControllerHandle and ChildHandle in the language specified by Language from the point of view of the driver specified by This. @retval EFI_SUCCESS The Unicode string for the user readable name in the language specified by Language for the driver specified by This was returned in DriverName. @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid EFI_HANDLE. @retval EFI_INVALID_PARAMETER Language is NULL. @retval EFI_INVALID_PARAMETER ControllerName is NULL. @retval EFI_UNSUPPORTED The driver specified by This is not currently managing the controller specified by ControllerHandle and ChildHandle. @retval EFI_UNSUPPORTED The driver specified by This does not support the language specified by Language. **/ EFI_STATUS EFIAPI IsaFloppyComponentNameGetControllerName ( IN EFI_COMPONENT_NAME_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE ChildHandle OPTIONAL, IN CHAR8 *Language, OUT CHAR16 **ControllerName ) { EFI_STATUS Status; EFI_BLOCK_IO_PROTOCOL *BlkIo; FDC_BLK_IO_DEV *FdcDev; if (Language == NULL || ControllerName == NULL) { return EFI_INVALID_PARAMETER; } // // This is a device driver, so ChildHandle must be NULL. // if (ChildHandle != NULL) { return EFI_UNSUPPORTED; } // // Check if this driver is currently managing ControllerHandle // Status = EfiTestManagedDevice ( ControllerHandle, gFdcControllerDriver.DriverBindingHandle, &gEfiIsaIoProtocolGuid ); if (EFI_ERROR (Status)) { return Status; } // // Get the device context // Status = gBS->OpenProtocol ( ControllerHandle, &gEfiBlockIoProtocolGuid, (VOID **) &BlkIo, gFdcControllerDriver.DriverBindingHandle, ControllerHandle, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); if (EFI_ERROR (Status)) { return Status; } FdcDev = FDD_BLK_IO_FROM_THIS (BlkIo); return LookupUnicodeString2 ( Language, This->SupportedLanguages, FdcDev->ControllerNameTable, ControllerName, (BOOLEAN)(This == &gIsaFloppyComponentName) ); }
EFI_STATUS EFIAPI FdcControllerDriverStop ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer ) /*++ Routine Description: Arguments: Returns: --*/ // GC_TODO: This - add argument and description to function comment // GC_TODO: Controller - add argument and description to function comment // GC_TODO: NumberOfChildren - add argument and description to function comment // GC_TODO: ChildHandleBuffer - add argument and description to function comment // GC_TODO: EFI_SUCCESS - add return value to function comment { EFI_STATUS Status; EFI_BLOCK_IO_PROTOCOL *BlkIo; FDC_BLK_IO_DEV *FdcDev; // // Get the Block I/O Protocol on Controller // Status = gBS->OpenProtocol ( Controller, &gEfiBlockIoProtocolGuid, (VOID **) &BlkIo, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); if (EFI_ERROR (Status)) { return Status; } // // Get the Floppy Disk Controller's Device structure // FdcDev = FDD_BLK_IO_FROM_THIS (BlkIo); // // Report disable progress code // ReportStatusCodeWithDevicePath ( EFI_PROGRESS_CODE, EFI_PERIPHERAL_REMOVABLE_MEDIA | EFI_P_PC_DISABLE, 0, &gEfiCallerIdGuid, FdcDev->DevicePath ); // // Turn the motor off on the Floppy Disk Controller // FddTimerProc (FdcDev->Event, FdcDev); // // Uninstall the Block I/O Protocol // Status = gBS->UninstallProtocolInterface ( Controller, &gEfiBlockIoProtocolGuid, &FdcDev->BlkIo ); if (EFI_ERROR (Status)) { return Status; } // // Close the device path protocol // gBS->CloseProtocol ( Controller, &gEfiDevicePathProtocolGuid, This->DriverBindingHandle, Controller ); // // Close the ISA I/O Protocol // gBS->CloseProtocol ( Controller, EFI_ISA_IO_PROTOCOL_VERSION, This->DriverBindingHandle, Controller ); // // Free the controller list if needed // FdcDev->ControllerState->NumberOfDrive--; // // Close the event for turning the motor off // gBS->CloseEvent (FdcDev->Event); // // Free the cache if one was allocated // FdcFreeCache (FdcDev); // // Free the Floppy Disk Controller's Device structure // EfiLibFreeUnicodeStringTable (FdcDev->ControllerNameTable); gBS->FreePool (FdcDev); return EFI_SUCCESS; }
/** Read or Write a number of blocks to floppy disk @param This Indicates a pointer to the calling context. @param MediaId Id of the media, changes every time the media is replaced. @param Lba The starting Logical Block Address to read from @param BufferSize Size of Buffer, must be a multiple of device block size. @param Operation Specifies the read or write operation. @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 performing the read. @retval EFI_NO_MEDIA There is no media in the device. @retval EFI_MEDIA_CHANGED The MediaId does not matched the current device. @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the 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. @retval EFI_WRITE_PROTECTED The device can not be written to. **/ EFI_STATUS FddReadWriteBlocks ( IN EFI_BLOCK_IO_PROTOCOL *This, IN UINT32 MediaId, IN EFI_LBA Lba, IN UINTN BufferSize, IN BOOLEAN Operation, OUT VOID *Buffer ) { EFI_BLOCK_IO_MEDIA *Media; FDC_BLK_IO_DEV *FdcDev; UINTN BlockSize; UINTN NumberOfBlocks; UINTN BlockCount; EFI_STATUS Status; EFI_LBA Lba0; UINT8 *Pointer; // // Get the intrinsic block size // Media = This->Media; BlockSize = Media->BlockSize; FdcDev = FDD_BLK_IO_FROM_THIS (This); if (Operation == WRITE) { if (Lba == 0) { FdcFreeCache (FdcDev); } } // // Set the drive motor on // Status = MotorOn (FdcDev); if (EFI_ERROR (Status)) { return EFI_DEVICE_ERROR; } // // Check to see if media can be detected // Status = DetectMedia (FdcDev); if (EFI_ERROR (Status)) { MotorOff (FdcDev); FdcFreeCache (FdcDev); return EFI_DEVICE_ERROR; } // // Check to see if media is present // if (!(Media->MediaPresent)) { MotorOff (FdcDev); FdcFreeCache (FdcDev); return EFI_NO_MEDIA; } // // Check to see if media has been changed // if (MediaId != Media->MediaId) { MotorOff (FdcDev); FdcFreeCache (FdcDev); return EFI_MEDIA_CHANGED; } if (BufferSize == 0) { MotorOff (FdcDev); return EFI_SUCCESS; } if (Operation == WRITE) { if (Media->ReadOnly) { MotorOff (FdcDev); return EFI_WRITE_PROTECTED; } } // // Check the parameters for this read/write operation // if (Buffer == NULL) { MotorOff (FdcDev); return EFI_INVALID_PARAMETER; } if (BufferSize % BlockSize != 0) { MotorOff (FdcDev); return EFI_BAD_BUFFER_SIZE; } if (Lba > Media->LastBlock) { MotorOff (FdcDev); return EFI_INVALID_PARAMETER; } if (((BufferSize / BlockSize) + Lba - 1) > Media->LastBlock) { MotorOff (FdcDev); return EFI_INVALID_PARAMETER; } if (Operation == READ) { // // See if the data that is being read is already in the cache // if (FdcDev->Cache != NULL) { if (Lba == 0 && BufferSize == BlockSize) { MotorOff (FdcDev); CopyMem ((UINT8 *) Buffer, (UINT8 *) FdcDev->Cache, BlockSize); return EFI_SUCCESS; } } } // // Set up Floppy Disk Controller // Status = Setup (FdcDev); if (EFI_ERROR (Status)) { MotorOff (FdcDev); return EFI_DEVICE_ERROR; } NumberOfBlocks = BufferSize / BlockSize; Lba0 = Lba; Pointer = Buffer; // // read blocks in the same cylinder. // in a cylinder , there are 18 * 2 = 36 blocks // BlockCount = GetTransferBlockCount (FdcDev, Lba, NumberOfBlocks); while ((BlockCount != 0) && !EFI_ERROR (Status)) { Status = ReadWriteDataSector (FdcDev, Buffer, Lba, BlockCount, Operation); if (EFI_ERROR (Status)) { MotorOff (FdcDev); FddReset (FdcDev); return EFI_DEVICE_ERROR; } Lba += BlockCount; NumberOfBlocks -= BlockCount; Buffer = (VOID *) ((UINTN) Buffer + BlockCount * BlockSize); BlockCount = GetTransferBlockCount (FdcDev, Lba, NumberOfBlocks); } Buffer = Pointer; // // Turn the motor off // MotorOff (FdcDev); if (Operation == READ) { // // Cache the data read // if (Lba0 == 0 && FdcDev->Cache == NULL) { FdcDev->Cache = AllocateCopyPool (BlockSize, Buffer); } } return EFI_SUCCESS; }