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; }
/** 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; }
/** 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; }